Socket.BeginReceive/EndReceive函数的调用顺序是怎样的?
例如,我调用了两次BeginReceive,一次获取消息长度,第二次获取消息本身。现在的场景是这样的,对于我发送的每个消息,我都开始等待其完成(实际上是消息发送的确认,同时在接收到确认后,我会等待操作完成),所以我会在每个BeginSend中调用BeginReceive,但在每个BeginReceive的回调中,我会检查我是否正在接收长度或消息。如果我接收的是消息并且已经完全接收到,那么我会调用另一个BeginReceive来接收操作的完成情况。现在问题就出在这里了。因为我的其中一个接收回调正在接收字节,并将其解释为消息的长度,而实际上它是消息本身。
现在该如何解决呢?
编辑:这是一个C#.NET的问题 :)
以下是代码,基本上太长了,抱歉
例如,我调用了两次BeginReceive,一次获取消息长度,第二次获取消息本身。现在的场景是这样的,对于我发送的每个消息,我都开始等待其完成(实际上是消息发送的确认,同时在接收到确认后,我会等待操作完成),所以我会在每个BeginSend中调用BeginReceive,但在每个BeginReceive的回调中,我会检查我是否正在接收长度或消息。如果我接收的是消息并且已经完全接收到,那么我会调用另一个BeginReceive来接收操作的完成情况。现在问题就出在这里了。因为我的其中一个接收回调正在接收字节,并将其解释为消息的长度,而实际上它是消息本身。
现在该如何解决呢?
编辑:这是一个C#.NET的问题 :)
以下是代码,基本上太长了,抱歉
public void Send(string message)
{
try
{
bytesSent = 0;
writeDataBuffer = System.Text.Encoding.ASCII.GetBytes(message);
writeDataBuffer = WrapMessage(writeDataBuffer);
messageSendSize = writeDataBuffer.Length;
clientSocket.BeginSend(writeDataBuffer, bytesSent, messageSendSize, SocketFlags.None,
new AsyncCallback(SendComplete), clientSocket);
}
catch (SocketException socketException)
{
MessageBox.Show(socketException.Message);
}
}
public void WaitForData()
{
try
{
if (!messageLengthReceived)
{
clientSocket.BeginReceive(receiveDataBuffer, bytesReceived, MESSAGE_LENGTH_SIZE - bytesReceived,
SocketFlags.None, new AsyncCallback(RecieveComplete), clientSocket);
}
}
public void Send(string message)
{
try
{
bytesSent = 0;
writeDataBuffer = System.Text.Encoding.ASCII.GetBytes(message);
writeDataBuffer = WrapMessage(writeDataBuffer);
messageSendSize = writeDataBuffer.Length;
clientSocket.BeginSend(writeDataBuffer, bytesSent, messageSendSize, SocketFlags.None,
new AsyncCallback(SendComplete), clientSocket);
}
catch (SocketException socketException)
{
MessageBox.Show(socketException.Message);
}
}
public void WaitForData()
{
try
{
if (! messageLengthReceived)
{
clientSocket.BeginReceive(receiveDataBuffer, bytesReceived, MESSAGE_LENGTH_SIZE - bytesReceived,
SocketFlags.None, new AsyncCallback(RecieveComplete), clientSocket);
}
else
{
clientSocket.BeginReceive(receiveDataBuffer, bytesReceived, messageLength - bytesReceived,
SocketFlags.None, new AsyncCallback(RecieveComplete), clientSocket);
}
}
catch (SocketException socketException)
{
MessageBox.Show(socketException.Message);
}
}
public void RecieveComplete(IAsyncResult result)
{
try
{
Socket socket = result.AsyncState as Socket;
bytesReceived = socket.EndReceive(result);
if (! messageLengthReceived)
{
if (bytesReceived != MESSAGE_LENGTH_SIZE)
{
WaitForData();
return;
}
// unwrap message length
int length = BitConverter.ToInt32(receiveDataBuffer, 0);
length = IPAddress.NetworkToHostOrder(length);
messageLength = length;
messageLengthReceived = true;
bytesReceived = 0;
// now wait for getting the message itself
WaitForData();
}
else
{
if (bytesReceived != messageLength)
{
WaitForData();
}
else
{
string message = Encoding.ASCII.GetString(receiveDataBuffer);
MessageBox.Show(message);
bytesReceived = 0;
messageLengthReceived = false;
// clear buffer
receiveDataBuffer = new byte[AsyncClient.BUFFER_SIZE];
WaitForData();
}
}
}
catch (SocketException socketException)
{
MessageBox.Show(socketException.Message);
}
}
public void SendComplete(IAsyncResult result)
{
try
{
Socket socket = result.AsyncState as Socket;
bytesSent = socket.EndSend(result);
if (bytesSent != messageSendSize)
{
messageSendSize -= bytesSent;
socket.BeginSend(writeDataBuffer, bytesSent, messageSendSize, SocketFlags.None,
new AsyncCallback(SendComplete), clientSocket);
return;
}
// wait for data
messageLengthReceived = false;
bytesReceived = 0;
WaitForData();
}
catch (SocketException socketException)
{
MessageBox.Show(socketException.Message);
}
}