【发布时间】:2010-11-26 04:34:29
【问题描述】:
Socket.BeginReceive/EndReceive 函数的调用顺序是什么?
例如,我调用 BeginReceive 两次,一次获取消息长度,第二次获取消息本身。现在的场景是这样的,对于我发送的每条消息,我都开始等待它的完成(实际上是对发送的消息的确认,也是在收到确认后等待动作完成),所以我调用 BeginReceive 对于每个 BeginSend,但在每个 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);
}
}
【问题讨论】:
-
可以添加代码/数据示例吗?
-
主要问题似乎是 (MESSAGE_LENGTH_SIZE - bytesReceived) 第一次可以正常工作 - 但之后不会是正确的消息长度大小,因为 bytesReceived 不再为 0。它有点难看当有此类事物的状态对象时,使用全局变量来传递这些东西。
-
问题不在那个,我调试了很多次,问题出来了,我调用BeginReceive 3次,2次接收长度,1次消息,但是调用顺序是,首先调用用于接收长度的回调,然后调用消息,但随后消息被破坏。所以我只需要知道回调被调用的顺序。
-
你能做到吗?我有同样的问题。你问这个问题已经很久了。我想你找到了解决办法。你能给我一些帮助吗?谢谢
标签: c# .net sockets beginreceive