【发布时间】:2013-12-16 11:45:12
【问题描述】:
我从客户端向正在使用 BeginReceive 侦听的服务器发送 2 个连续数据包
服务器总是接收第一个数据包而不是另一个数据包,除非我在调试模式下运行客户端并在另一个之后缓慢发送下一个数据包。
这是我发送函数的一个 sn-p
if (soc.Connected)
{
byte[] byData = new byte[System.Text.Encoding.ASCII.GetByteCount("Hi")];
byData = System.Text.Encoding.ASCII.GetBytes("Hi");
soc.Send(BitConverter.GetBytes(byData.Length));
soc.Send(byData);
}
这是位于我的服务器内部的回调函数:
private void Recieve(IAsyncResult iar)
{
int j = 0;
Socket server_conn = (Socket)iar.AsyncState;
server_conn.EndReceive(iar);
if (!SocketConnected(server_conn))
{
server_conn.Close();
return;
}
if (g_bmsg.Length != 0)
{
logthis(server_conn.RemoteEndPoint.ToString() + ": " + Encoding.ASCII.GetString(g_bmsg, 0, g_bmsg.Length));
}
//Find out who sent this
foreach (ClientData cls in clientlist)
{
if (server_conn.RemoteEndPoint == cls.clientsock.RemoteEndPoint)
{
j = cls.index;
break;
}
}
server_conn.BeginReceive(g_bmsg, 0, g_bmsg.Length, SocketFlags.None, new AsyncCallback(Recieve), server_conn);
}
【问题讨论】:
-
g_bmsg在哪里定义?它是如何分配的?如果您在第一条消息中收到长度,然后在第二条消息中收到数据,会发生什么?任何合理的通信协议实现都应该包括一个 FIFO 缓冲区和一个允许拆分消息的解析器。 -
g_bmsg 定义在 Form1 类 private byte[] g_bmsg = new byte[1024];我没有对我的服务器进行编码,除了阅读下一条消息的长度,因为我只是在测试它。
-
并且可能作为缓冲区参数传递给
Socket.BeginReceive。 -
是的,它在第一次启动 BeginReceive 时通过。我应该为每个客户创建一个单独的缓冲区还是我在这里缺少什么?
-
不保证
Send和Receive调用之间的一一对应关系。由于您似乎正在发送少量数据,因此第一个Receive很可能正在用分别发送的两条消息填充缓冲区。
标签: c# sockets asynchronous