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个字符的变体。我以为接收方只会用传入的数据填充缓冲区,但不知何故,它正在用重复的数据填充缓冲区。

这里有两个问题:

  1. 我应该用什么,流。写/读还是客户端/发送/接收?
  2. 如何确保这个答案验证?

Socket客户端应答

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 +分隔符

然后在读取时解析