异步套接字写入 - 发送操作有可能混淆吗?(.NET 套接字)

Der*_*mot 5 .net c# sockets

抱歉,如果之前有人问过这个问题,但我发现很难搜索:

如果我BeginSend().NET socket上使用,我应该在与此(伪)代码类似的代码中期望什么样的行为:

主程序代码:

Network.OutBound.SendData(messageOne);

Network.OutBound.SendData(messageTwo);
Run Code Online (Sandbox Code Playgroud)

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
     }
}
Run Code Online (Sandbox Code Playgroud)

正如我使用的那样BeginSend(),当第一个SendData(messageOne)被调用时,它将立即返回,第二个SendData(messageTwo)将被调用。但是,请考虑这样一种情况:消息 1 和消息 2 都发送了大量数据,并且发送完成了部分数据量,因此BeginSend()被召回以发送剩余数据。

这会导致传出套接字中的两个消息字节混淆吗?它们都将在单独的线程池线程中运行,并且都将在同一个套接字上发送。我理解 TCP 套接字确保数据按顺序到达,但是运行时/套接字层如何知道我BeginSend()是后续尝试完成发送 messageOne 还是 messageTwo 的开始?就它而言,在远程端发送和接收的数据不会与写入套接字的顺序相同(即使这似乎是混淆的可能性)

如果是这样,如果我必须序列化对它的访问,Begin/End Send 的意义何在?

我是否应该在完全发送 messageOne 时设置某种标志(即使需要多次BeginSend()尝试发送所有数据),以便主程序代码可以在尝试发送不同的消息之前等待它完成?

我应该编写某种传出队列包装器吗?或者我错过了什么?

Pau*_*rry 4

使用 Reflector 进行查看,您将看到 BeginSend 最终从 .NET 包装器退出到 Win32 API,并调用WSASend,而 WSASend 似乎没有提供任何形式的 ASync 选项,因此据我所知,它只会使用线程池生成在 .NET 框架内管理的异步调用。

在我用网络编写的应用程序中,我从未真正考虑过这种情况,因为我有一个发送者方法,如果您尝试在上一个发送完成之前再次调用它,它会被阻止,或者我总是使用 .Send 阻止只是因为它们通常是对专用线程上收到的消息的响应。

编辑:

做了一些额外的测试。

如果你开始 2 个开始和结束,每个缓冲区都很小,那么它可能不会真正产生影响,但如果你的缓冲区很大,我的测试我使用了 400k 缓冲区,那么你肯定会受到伤害,你希望只是例外,但它会崩溃。