c#TCP套接字停止接收数据包

时间:2018-05-23 12:31:04

标签: c# tcpsocket

我有一个问题:

我的模型是1台服务器使用TCP套接字模型同时为大量客户端提供服务。 代码通常工作正常,从不抛出任何异常,但有时服务器和客户端之间的连接会像这样:

+)客户端成功向服务器发送数据(我知道这是因为使用WireShark来捕获服务器端的每个数据包)

+)服务器socket.Receive(缓冲区)不显示上面的任何数据。 (为什么?)//它是一个接收循环,所以它必须是零接收后的一些数据吗?但看起来它永远不会像往常一样接受。

+)服务器向客户端发送数据(通常每隔500毫秒发送一次)

+)客户端仍然能够从服务器

接收数据

圈子继续这样。

我需要知道为什么Server保持“拒绝”(idk)数据来自客户端,就像连接看起来那样好?

这是发送我用于双方的方法:Socket.Send(Encoding.UTF8.GetBytes(“Message $”);

这是我用于双方的接收方法,请注意每条消息以“$”结尾以将它们分开。

int Signal(Socket s, byte[] b)
    {
        int k = 0;
        try { k = s.Receive(b); return k; } catch { return 0; }
    }

void Receiverr(Socket s){
     new thread(()=>
     {byte[] byteReceive = new byte[1024];
            Array.Clear(byteReceive, 0, byteReceive.Length);
            while (s.Connected)
            {
                string msg = "";
                int n = Signal(s, byteReceive);
                if (n == 0) { Array.Clear(byteReceive, 0, byteReceive.Length); continue; }
                msg = Encoding.UTF8.GetString(byteReceive);
                textBox2.Text += "n = " + n.ToString() + Environment.NewLine; // i use this to see if any byte that i could miss
                msg = msg.Replace("\0", "");
                string[] arrray_save = msg.Split('$');
                foreach (string message in arrray_save)
                {
                     //do my work
                }
                Array.Clear(byteReceive, 0, byteReceive.Length); continue;
            }
            try{s.Shutdown(SocketShutdown.Both); s.Close();}
            catch{}
     }
  }){isBackGround = true}.Start();       

我已经忍受了好几个星期:(对不起英语不好,任何帮助都不得不欣赏。

编辑(2018年5月24日) 这是我的新代码,以确保数据正确接收但问题仍然存在

byte[] data_save = new byte[1024]; int index = 0;
while (s.Connected)
            {
                int n = s.Available;
                if (n == 0) { continue; }
                byte[]byteReceive = new byte[n];
                s.Receive(byteReceive);
                byteReceive.CopyTo(data_save, index);
                index += byteReceive.Length;

                string test = Encoding.UTF8.GetString(data_save).Replace("\0", "");
                if (test[test.Length - 1] != '$') { continue; }
                textBox2.Text += test + Environment.NewLine;
                Array.Clear(data_save, 0, data_save.Length);
                index = 0;

                string[] array_save = test.Split('$');
                foreach (string message in array_save)
                {
                     //do my work
                }
         }try { s.Shutdown(SocketShutdown.Both); s.Close();} catch { }

2 个答案:

答案 0 :(得分:2)

这是正确的套接字读取循环。您似乎假设单个Receive()将始终返回完整的消息。 TCP / IP是一种流协议,没有消息概念。每次对Receive的调用可能少于整个消息。您的服务器必须知道预期的字节数,或者数据中的某个指示符以指示何时收到完整的消息。也不要吞下例外。

参见例如

  

"人们设计中最常见的初学者错误之一   TCP / IP的协议是它们假设消息边界是   保存。例如,他们假设单个“发送”将导致a   单个“接收”。"

Message Framing

答案 1 :(得分:0)

万一有人需要,一个foreach和解决方案的线程。