Socket.SendAsync不是在Mono / Linux上按顺序发送的

有一个使用.NET Socket和TCP协议的单线程服务器,
Socket.Pool()
Socket.Select()
Socket.Receive()
。 要发送,我用过:
public void SendPacket(int clientid, byte[] packet)
{
    clients[clientid].socket.Send(packet);
}
但是当向一个客户端发送大量数据(暂停整个主线程)时速度非常慢,所以我将其替换为:
public void SendPacket(int clientid, byte[] packet)
{
    using (SocketAsyncEventArgs e = new SocketAsyncEventArgs())
    {
        e.SetBuffer(packet, 0, packet.Length);
        clients[clientid].socket.SendAsync(e);
    }
}
它在带有.NET的Windows上工作正常(我不知道它是否完美),但在使用Mono的Linux上,数据包被丢弃或重新排序(我不知道)。使用Socket.Send()恢复为慢速版本适用于Linux。整个服务器的来源。 如何编写适用于Linux的非阻塞SendPacket()函数?     
已邀请:
我要猜测它与你的
using
声明和你的
SendAsync
电话有关。也许
e
超出范围并且正在处理,而
SendAsync
仍在处理缓冲区。但是这可能会引发异常。我真的只是在猜测。尝试删除
using
语句,看看会发生什么。     
我会说不滥用异步方法。你将找不到任何文件说明这个实际上被迫维持秩序。它将iem排队到一个被分配给线程的scheuler,并且忽略了每个文档都没有维护oder,你可以自己打开实现细节。 最好的可能是: 每个插槽都有一个队列。 当您将dasta写入此队列并且没有工作线程时,启动工作项(ThreadPool)来处理该线程。 这样,您就可以使用单独的不同队列来维护顺序。只有一个线程会处理一个队列/套接字。     
我遇到了同样的问题; Linux和Windows对SendAsync的反应方式不同。有时linux会截断数据,但有一种解决方法。首先,您需要使用队列。每次使用SendAsync时都必须检查回调。 如果e.Offset + e.BytesTransferred< e.Buffer.Length,你只需要e.SetBuffer(e.Offset + e.BytesTransferred,e.Buffer.Length - e.BytesTransferred - e.Offset);并再次调用SendAsync。 我不知道为什么mono-linux相信它在发送所有数据之前已经完成了,这很奇怪,但我确信他确实如此。     

要回复问题请先登录注册