Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#从套接字读取二进制数据_C#_Sockets_Tcp_Binary - Fatal编程技术网

C#从套接字读取二进制数据

C#从套接字读取二进制数据,c#,sockets,tcp,binary,C#,Sockets,Tcp,Binary,我正在开发一个应用程序,它可以从套接字读取和写入二进制数据。因此,首先我使用TcpClient创建一个套接字。但我一直在从套接字读取数据。有关于如何从套接字读取二进制数据的代码示例吗 具体来说,有两件事我不明白。首先,我如何知道消息是否已“收到”?我需要为此创建某种循环吗?第二:读取这些数据的最佳方式是什么,因为我接收的数据是二进制的,而不仅仅是普通的字符串 谢谢通过套接字发送的所有数据都是二进制的。您可以将其解释为其他内容,例如字符串。您可以使用这些函数来发送或接收数据。您可以使用从Netwo

我正在开发一个应用程序,它可以从套接字读取和写入二进制数据。因此,首先我使用TcpClient创建一个套接字。但我一直在从套接字读取数据。有关于如何从套接字读取二进制数据的代码示例吗

具体来说,有两件事我不明白。首先,我如何知道消息是否已“收到”?我需要为此创建某种循环吗?第二:读取这些数据的最佳方式是什么,因为我接收的数据是二进制的,而不仅仅是普通的字符串


谢谢

通过套接字发送的所有数据都是二进制的。您可以将其解释为其他内容,例如字符串。您可以使用这些函数来发送或接收数据。您可以使用从
NetworkStream=client.GetStream()获取的NetworkStream调用它们。注意,这些函数首先发送一个带有数据大小的int

public void send(NetworkStream stream, byte[] buf) {
    stream.Write(BitConverter.GetBytes(buf.Length), 0, 4);
    stream.Write(buf, 0, buf.Length);
}

public byte[] receive(NetworkStream stream) {
    byte[] lengthBytes = new byte[4];
    int read = stream.Read(lengthBytes, 0, 4);
    // read contains the number of read bytes, so we can check it if we want
    int length = BitConverter.GetInt32(lengthBytes);
    byte[] buf = new byte[length];
    stream.Read(buf, 0, buf.length);
    return buf;
}

在这种情况下,我将遵从MSDN。具体来说,使用(维护连接-您已经在这样做了),(接受连接并开始通信)以及(将数据转换为二进制文件或从二进制文件转换数据)。

第一步是在TcpClient实例上调用GetStream,它提供对用于发送和接收二进制数据的网络流的引用。您可以将其包装在BinaryReader和BinaryWriter中,以发送和接收.NET原语(如Int32s、字符串等),或者直接将NetworkStream方法用于字节数组。您会发现NetworkStream.Read、NetworkStream.beginhead和NetworkStream.DataAvailable成员非常有用;有关更多信息,请参阅。

来自Microsoft的信息实际上非常有用

如何从TCP客户端读取数据

Microsoft示例中从套接字读取数据的关键部分如下:

// Get the stream
NetworkStream stream = client.GetStream();
Byte[] data = new Byte[256];

// String to store the response ASCII representation.
String responseData = String.Empty;

// Read the first batch of the TcpServer response bytes.
int bytes = stream.Read(data, 0, data.Length);
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
它们使用类的方法并从流中读取所有可用数据(最多256字节)

不过这有点作弊,因为他们只是接收到一堆数据,并假设这是一条完整正确的消息。只要你的客户端是100%可预测的,它就会工作得很好,因为它总是发送相同的东西,然后断开连接

下面是更好的处理方法

您如何知道是否收到了邮件?

你不需要,你只需要一直接收数据,直到没有更多的数据,然后检查你收到的数据(或者边走边检查)

要做到这一点,您必须设计消息,使其包含某种表示长度的方式(开始处的整数表示长度),或具有消息结尾标记(例如回车符)或具有固定长度的消息

例如,您的消息规范可能如下所示:

资料 你好,朋友
结束

通过查找结尾,然后查找回车符,您将知道您已找到消息的结尾。同样,开头的
数据
标记帮助您判断消息的起始位置,并拆分消息数据

读取此数据的最佳方式是什么?

所有发送/接收的数据都是二进制的,您需要对数据进行编码和解码。在本例中,他们使用内置的ASCII编码类和方法将二进制数据转换为字符串(反之亦然)

考虑实施已知协议

我建议(在可能的情况下)使用已建立的协议,而不仅仅是通过TCP发送纯文本。几乎任何东西都有标准,任何连接到您的应用程序的人都会发现遵循已知和定义的标准更容易


还有许多用于常用协议的预构建库,为您和您的客户省去了很多麻烦。

OP使用的是TcpClient,而不是直接使用套接字。读取tcp流要复杂得多,因为stream.Read()可能并不总是读取预期的字节数。您对文档有什么问题吗?还有一个很好的例子: