Socket客户端应答
本文关键字:应答 客户端 Socket | 更新日期: 2023-09-27 18:11:41
我正在创建一个客户端/服务器套接字应用程序。我无法解决这个问题,可能是由于缺乏对此事的了解。
客户端必须发送应答才能继续通信:
while(comunicate)
{
if (chkCorrectAnswer.Checked)
answer = encoder.GetBytes(''x02' + "82SP|" + ''x03');
else
answer = encoder.GetBytes("bla");
ServerStream.Write(answer, 0, answer.Length);
//or ??
//tcp.Client.Send(answer);
}
服务器接收它:
while(comunicate)
{
var validanswer= encoder.GetBytes("myvalidanswer");
answer = new byte[validanswer.Length];
stream.Read(answer, 0, validanswer.Length);
//or ??
//tcp.Client.Receive(answer);
if (answer.SequenceEqual(validanswer))
// continue communication
}
每个代码都在不同的应用程序中,循环"通信线程"。
答案似乎被正确发送,但服务器似乎没有正确接收它。有时它接收blablab或lablabl以及7个字符的变体。我以为接收方只会用传入的数据填充缓冲区,但不知何故,它正在用重复的数据填充缓冲区。
这里有两个问题:
- 我应该用什么,流。写/读还是客户端/发送/接收?
- 如何确保这个答案验证?
0x02和0x03被称为文本开始(STX)和文本结束(ETX),它们是用于标识消息开始和结束的分隔符。确实没有必要同时使用,这是在进行串行通信时的常见做法。
您需要继续构建消息,直到接收到ETX。
类似于(最简单的解决方案,但如果您有很多客户端,则不是很有效)
string buffer = "";
var readBuffer = new byte[1];
int readBytes = 0;
while ((readBytes = stream.Read(readBuffer, 0, 1)) == 1 && readBuffer[0] != 3)
{
buffer += readBuffer[0];
}
当然可以读取更大的块。但是您需要检查是否有多个消息到达,并相应地处理缓冲区。我就是这么做的
我以为接收方只会用传入的数据填充缓冲区,但不知何故,它却用重复的数据填充缓冲区。
嗯,你在循环中反复发送数据,所以这是意料之中的。
如果你只想从流中读取一定数量的字节,你还需要在它之前发送逻辑数据包的大小,以便接收端可以首先读取大小(例如作为固定的int值),然后是实际的响应。
当你阅读时,你会得到你写的所有内容,包括你以前写过的所有内容。
实现一个长度头或某种分隔符,这样你就知道什么是什么了——
长度+信息
或
message +分隔符
然后在读取时解析