我有个问题:
我的模型是一台服务器同时为多个客户端提供服务,使用TCP套接字模型。代码通常运行良好,不会抛出任何异常,但有时服务器和客户端之间的连接如下所示:
+)客户端成功地将数据发送到服务器(我知道这一点,因为我使用WireShark来捕获服务器端的每个数据包)
+)服务器缓冲区(socket.Receive)不显示上述任何数据。(为什么?)//它是一个接收循环,所以它必须是零接收后的一些数据对吗?但看起来它永远不会再接收了。
+)服务器向客户端发送数据(通常每500ms发送一次)
+)客户端仍然能够从服务器接收数据
这样的圆圈还在继续。
我想知道为什么服务器一直“拒绝”(Idk)来自客户端的数据,而连接看起来却没有问题?
下面是我用于两端发送方法: Socket.Send(Encoding.UTF8.GetBytes("Message$");
这是我对两端使用的方法Receive,请注意,每条消息都以"$“结尾,以便在另一端分隔它们。
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 { }发布于 2018-05-23 21:43:21
这不是正确的套接字读取循环。您似乎假设一次接收()总是会返回一条完整的消息。TCP/IP是一种流协议,没有消息的概念。要接收的每个呼叫可能少于整个消息。您的服务器必须知道它期望的字节数,或者知道数据中的某个指示符,以指示何时接收到完整的消息。另外,不要吞下异常。
请参见例如
对于为
/IP设计协议的人来说,最常见的初学者错误之一是他们认为消息边界是保留的。例如,他们假设一次“发送”将导致一次“接收”。
发布于 2018-05-26 18:51:04
如果有人需要,一个线程的foreach和事情都解决了。
https://stackoverflow.com/questions/50488484
复制相似问题