我正在创建一个客户端/服务器套接字应用。而且我无法解决这个问题,可能是因为对此事缺乏了解。
客户必须发送答案才能继续沟通:
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个字符的变化。我接收到的只会使用传入的数据填充缓冲区,不知何故,它会用重复的数据填充缓冲区。
这里有两个问题:
答案 0 :(得分:1)
我接收到的只会用传入的数据填充缓冲区,不知怎的,它会用重复的数据填充缓冲区。
好吧,你是在循环中重复发送数据,所以这是可以预料的。
如果您只想从流中读取一定数量的字节,您还需要在其前面发送逻辑数据包的大小,以便接收端可以首先读取大小(比如固定的int值)和那么实际的反应。
答案 1 :(得分:1)
当你阅读时,你会得到你写的所有内容,包括你之前写过的东西。
实现一个长度标题或某种分隔符,以便您知道它是什么 -
长度+消息
或
消息+分隔符
然后在阅读时解析它。
答案 2 :(得分:1)
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];
}
你当然可以阅读更大的块。但是,您需要检查是否有多条消息到达并相应地处理缓冲区。我就是这样做的。