我从客户端向使用BeginReceive
监听的服务器发送2个连续数据包如果我在调试模式下运行客户端并慢慢发送下一个数据包,服务器总是收到第一个数据包但不接收另一个数据包。
这是我发送功能的片段
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);
}
答案 0 :(得分:1)
使用TCP / IP套接字(或几乎任何通信层)时,您很少能保证您要发送的整个邮件将包含在一个数据包中。
这意味着您应始终保留自己的FIFO缓冲区,并按顺序解析它。
这是一般的想法:
// fifo queue (for background thread parsing, make sure it's thread safe)
private readonly ConcurrentQueue<byte> _commQueue = new ConcurrentQueue<byte>();
在Receive
方法中,您应该简单地将数据排入FIFO:
private void Receive(IAsyncResult iar)
{
Socket server_conn = (Socket)iar.AsyncState;
// check how many bytes we actually received
var numBytesReceived = server_conn.EndReceive(iar);
if (!SocketConnected(server_conn))
{
server_conn.Close();
return;
}
// get the received data from the buffer
if (numBytesReceived > 0)
{
for (int i = 0; i < numBytesReceived; i++)
_commQueue.Enqueue(g_bmsg[i]);
// signal the parser to continue parsing
NotifyNewDataReceived();
}
// continue receiving
server_conn.BeginReceive(g_bmsg, 0, g_bmsg.Length, SocketFlags.None, new AsyncCallback(Recieve), server_conn);
}