C#Socket接收混乱的数据

时间:2016-04-12 18:29:39

标签: c# sockets

我正在尝试创建一个通过套接字进行通信的客户端/服务器应用程序。但是当我收到数据时,它会随机乱搞并且总是(有时)显示正确的数据。我用来接收数据的代码:

private static void ReceiveCallback(IAsyncResult AR)
{
     try
     {
        Socket socket = (Socket)AR.AsyncState;
        if (SocketConnected(socket))
        {
           int received = socket.EndReceive(AR);
           byte[] dataBuf = new byte[received];
           Array.Copy(_buffer, dataBuf, received);
           string text = Encoding.ASCII.GetString(dataBuf);
           if (!text.Contains("GET") && !text.Contains("HTTP") && text != null)
           {
                Console.WriteLine(DateTime.Now.ToString("h:mm:ss tt") + ":" + text);
           }
           socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
         }
      }
      catch
      {

      }   
}

有人能解释我为什么会这样吗?提前谢谢!

此外,我试图检查,直到它找到一个字符(这是在每个回复的结尾' - '但这不起作用)。不幸的是结果:Output

3 个答案:

答案 0 :(得分:1)

我认为你的套接字是一个TCP套接字,因为你正在处理像HTTP这样的东西。

TCP处理流而不是消息。因此,当您执行读操作时,从流中读取最多_buffer.Length个字节。这意味着您可以轻松读取响应的一部分 - 或者更确切地说,响应将在多个回调之间分配。当你偶然阅读时,一切都按预期工作。在localhost上进行测试时尤其如此,因为Windows对localhost TCP的处理方式与非localhost情况有很大不同。但是当它阅读时,text将不包含整个响应 - 并且您的数据已被破坏。

此外,当received为零时,表示对方关闭了流,您应该停止BeginReceive

答案 1 :(得分:1)

您需要循环接收套接字,直到收到完整的消息。

这也意味着您必须具有应用程序级协议。什么定义了消息?

终止角色?然后循环阅读,直到你得到那个角色。

字符数?然后循环读取,直到你得到那么多字符。

消息前面的消息长度是多少?然后循环,直到你得到足够的字节来获取长度,然后循环,直到你得到整个消息。

答案 2 :(得分:0)

您的套接字代码对我来说很好。 .Net世界中编码格式的字符是“Unicode”,您应该将接收的字节转换为Unicode而不是ASCII:

string text = Encoding.Unicode.GetString(dataBuf);