我有一个问题:
我的模型是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 { }
答案 0 :(得分:2)
这是不正确的套接字读取循环。您似乎假设单个Receive()将始终返回完整的消息。 TCP / IP是一种流协议,没有消息概念。每次对Receive的调用可能少于整个消息。您的服务器必须知道预期的字节数,或者数据中的某个指示符以指示何时收到完整的消息。也不要吞下例外。
参见例如
"人们设计中最常见的初学者错误之一 TCP / IP的协议是它们假设消息边界是 保存。例如,他们假设单个“发送”将导致a 单个“接收”。"
答案 1 :(得分:0)
万一有人需要,一个foreach和解决方案的线程。