非常抱歉,如果此问题以前已经被问过,但我发现它很难搜索:
如果在.NET套接字上使用BeginSend()
,则在类似于以下(伪)代码的代码中应该期望哪种行为:
主要程序代码:
Network.OutBound.SendData(messageOne);
Network.OutBound.SendData(messageTwo);
Network.OutBound类
public void SendData(byte[] buffer)
{
connectedSocket.BeginSend(buffer,0,buffer.Length,SocketFlags.None,SendCompleteMethod);
}
private void SendComplete(arResult)
{
int bytesSent;
bytesSent = arResult.EndSend();
if(bytesSent < arResult.state.buffer.Length)
{
//Not all data sent yet, recall BeginSend
connectedSocket.BeginSend(buffer,bytesSent,buffer.Length - bytesSent,SocketFlags.None,SendCompleteMethod);
}
else
{
//All data sent successfully
}
}
由于我正在使用BeginSend()
,因此在调用第一个SendData(messageOne)
时,它将立即返回并调用第二个SendData(messageTwo)
。
然而,考虑这样一种情况:大量数据正在发送消息一和消息二,发送完成后仅有部分数据,因此BeginSend()
被重新调用以发送剩余的数据。
这会导致两个消息的字节在传出套接字中混合吗?
它们都将在单独的线程池线程中运行,并且都将在同一个套接字上发送。我理解TCP套接字确保数据按顺序到达,但是运行时/套接字层如何知道我的BeginSend()
是完成发送messageOne的后续尝试,还是messageTwo的开始?对它来说,数据是否不是按照写入套接字的顺序发送和接收到远程端点(即使这是可能混淆的地方)
如果是这样,那么如果我必须序列化访问它,那么Begin/End Send的意义是什么呢?
我应该有某种标志,当messageOne已完全发送时触发(即使需要多次BeginSend()
尝试发送所有数据),以便主程序代码在尝试发送不同的消息之前等待它完成吗?
我应该编写某种传出队列包装器吗?还是我漏掉了什么?