首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >c# TCP套接字停止接收数据包

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

Stack Overflow用户
提问于 2018-05-23 20:31:04
回答 2查看 948关注 0票数 2

我有个问题:

我的模型是一台服务器同时为多个客户端提供服务,使用TCP套接字模型。代码通常运行良好,不会抛出任何异常,但有时服务器和客户端之间的连接如下所示:

+)客户端成功地将数据发送到服务器(我知道这一点,因为我使用WireShark来捕获服务器端的每个数据包)

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

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

+)客户端仍然能够从服务器接收数据

这样的圆圈还在继续。

我想知道为什么服务器一直“拒绝”(Idk)来自客户端的数据,而连接看起来却没有问题?

下面是我用于两端发送方法: Socket.Send(Encoding.UTF8.GetBytes("Message$");

这是我对两端使用的方法Receive,请注意,每条消息都以"$“结尾,以便在另一端分隔它们。

代码语言:javascript
运行
复制
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日)以下是我的新代码,以确保接收的数据正确,但问题仍然存在

代码语言:javascript
运行
复制
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 { }
EN

Stack Overflow用户

发布于 2018-05-23 21:43:21

这不是正确的套接字读取循环。您似乎假设一次接收()总是会返回一条完整的消息。TCP/IP是一种流协议,没有消息的概念。要接收的每个呼叫可能少于整个消息。您的服务器必须知道它期望的字节数,或者知道数据中的某个指示符,以指示何时接收到完整的消息。另外,不要吞下异常。

请参见例如

对于为

/IP设计协议的人来说,最常见的初学者错误之一是他们认为消息边界是保留的。例如,他们假设一次“发送”将导致一次“接收”。

Message Framing

票数 2
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50488484

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档