我是 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 字节的固定 byte[] 数组中。
byte[] bb = new byte[100];
int k = stm.Read(bb, 0, 100);
如果服务器的响应超过 100 字节怎么办?在不知道服务器数据最大长度的情况下如何读取数据?
通常,在没有某些特定的固有大小的情况下,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);
然后,当接收器读取长度字符串时,它确切地知道糊状数据应该如何遵循(良好的编程实践是信任但验证——如果真正发送的数据或多或少——比如通过'邪恶的演员”——你需要做好应对的准备)。
你好,我用一个列表解决了它,我不知道完整包的大小,但我可以分部分阅读它
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);
我用图像做这个,看起来不错,我认为如果海豚读取了未知大小的完整源,你不知道数据的大小
不是针对 C#,而是关于编写 TCP 应用程序的一般答案:
TCP 是基于流的协议。它不维护消息边界。因此,使用 TCP 的应用程序应该注意选择服务器和客户端之间正确的数据交换方法。如果在一个连接上发送和接收多条消息,它就变得更加重要。
一种广泛使用的方法是在数据消息前面添加长度字节。
例如:
[2 byte -length field][Actual Data]
.
此类数据的接收方(无论是服务器还是客户端,都需要解码长度字段,等待接收到尽可能多的字节,或者发出超时警报并放弃。
另一个可以使用的协议是让应用程序维护消息边界。
例如: `[MSG 开始][实际数据][MSG 结束]
接收方必须解析数据的起始字节和结束字节(由应用程序协议预定义),并将中间的任何内容视为感兴趣的数据。
我四处寻找这个问题的答案,并注意到可用属性已添加到 TcpClient。它返回可供读取的字节数。
我假设它是在大多数回复之后添加的,所以我想与可能偶然发现这个问题的其他人分享。