如何在TCP客户端中读取未知数据长度

本文关键字:未知数 未知 数据 读取 TCP 客户端 | 更新日期: 2023-09-27 18:21:04

我是C#的新相对论。在我的TCP客户端中有以下功能,它将数据发送到服务器并返回响应:

private static TcpClient tcpint = new TcpClient(); //Already initiated and set up
private static NetworkStream stm;                  //Already initiated and set up
private static String send(String data)
{
    //Send data to the server
    ASCIIEncoding asen = new ASCIIEncoding();
    byte[] ba = asen.GetBytes(data);
    stm.Write(ba, 0, ba.Length);
    //Read data from the server
    byte[] bb = new byte[100];
    int k = stm.Read(bb, 0, 100);
    //Construct the response from byte array to string
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < k; i++)
    {
        sb.Append(bb[i].ToString());
    }
    //Return server response
    return sb.ToString();
}

正如您在这里看到的,当我从服务器读取响应时,我将其读取到一个长度为100字节的fix-byte[]数组中。

byte[] bb = new byte[100];
int k = stm.Read(bb, 0, 100);

如果服务器的响应超过100字节,我该怎么办?我如何在不知道服务器数据的最大长度的情况下读取数据?

如何在TCP客户端中读取未知数据长度

通常,在没有特定的内部大小的情况下,tcp协议会显式地发送它们正在发送的对象的长度。一种可能的说明方法:

size_t data_len = strlen(some_data_blob);
char lenstr[32];
sprintf(lenstr, "%zd'n", data_len);
send(socket, lenstr, strlen(lenstr));
send(socket, some_data_blob, data_len);

然后,当接收器读取长度字符串时,它确切地知道应该遵循多少mush数据(良好的编程实践是信任但验证——如果确实发送了或多或少的数据——比如说由的"恶意行为者"发送——你需要准备好处理它)。

不是关于C#,而是关于编写TCP应用程序的一般答案:

TCP是基于蒸汽的协议。它不维护消息边界。因此,使用TCP的应用程序应该注意选择正确的服务器和客户端之间的数据交换方法。如果在一个连接上发送和接收多条消息,那么它将变得更加重要。

一种广泛使用的方法是在数据消息前加上长度字节。

例如:

CCD_ 1。

此类数据的接收器(无论是服务器还是客户端,都需要解码长度字段,等待直到接收到如此多字节的事件,或者在超时时发出警报并放弃。

可以使用的另一个协议是让应用程序维护消息边界。

例如:`[START of MSG][Actual Data][END of MSG]

接收器必须解析开始字节和结束字节(由应用程序协议预定义)的数据,并将两者之间的任何数据视为感兴趣的数据。

你好,我用一个列表解决了它,我不知道整个包的大小,但我可以在中阅读

List<byte> bigbuffer = new List<byte>();
byte[] tempbuffer = new byte[254]; 
//can be in another size like 1024 etc.. 
//depend of the data as you sending from de client
//i recommend small size for the correct read of the package
NetworkStream stream = client.GetStream();
while (stream.Read(tempbuffer, 0, tempbuffer.Length) > 0) {
    bigbuffer.AddRange(tempbuffer);
} 
// now you can convert to a native byte array
byte[] completedbuffer = new byte[bigbuffer.Count];
bigbuffer.CopyTo(completedbuffer);
//Do something with the data
string decodedmsg = Encoding.ASCII.GetString(completedbuffer);

我用图像做这件事,看起来很好,我认为如果用未知大小的读取海豚的完整来源,你可能不知道数据的大小

我四处寻找答案,注意到Available属性已添加到TcpClient中。它返回可供读取的字节数。

我想它是在大多数回复之后添加的,所以我想把它分享给其他可能偶然发现这个问题的人。

https://learn.microsoft.com/en-us/dotnet/api/system.net.sockets.tcpclient.available?view=netframework-4.8