C# Mono Socket服务器在执行大型操作时会丢弃客户端
单声道3.99 我的socket服务器在Windows中运行良好,但在Linux/Mono上它会丢失一个套接字。 每当服务器运行操作的时间超过几分之一秒时,套接字就会断开连接,但有时客户端会保持连接。客户端是Silverlight 4,从Windows运行 当两个客户端连接时,更容易复制。第一个连接良好。第二个连接,但当服务器运行操作时,我的服务器断开第一个客户端的连接。发生这种情况时,第一个客户机正好发送0个字节 我将我的客户机放在一个静态列表中,这样它们就不会被GC'd,并且超时设置为高。我能想到的唯一一件事是客户端可能正在ping服务器,在处理消息的时间窗口中,它没有处于接收状态。但这将使插座极为脆弱 是否有任何原因(与Mono相关或其他原因)会导致这种行为C# Mono Socket服务器在执行大型操作时会丢弃客户端,c#,sockets,mono,C#,Sockets,Mono,单声道3.99 我的socket服务器在Windows中运行良好,但在Linux/Mono上它会丢失一个套接字。 每当服务器运行操作的时间超过几分之一秒时,套接字就会断开连接,但有时客户端会保持连接。客户端是Silverlight 4,从Windows运行 当两个客户端连接时,更容易复制。第一个连接良好。第二个连接,但当服务器运行操作时,我的服务器断开第一个客户端的连接。发生这种情况时,第一个客户机正好发送0个字节 我将我的客户机放在一个静态列表中,这样它们就不会被GC'd,并且超时设置为高。我
static void OnBeginAccept(IAsyncResult ar)
{
try
{
TcpClient _MessageClient = _MessageListener.EndAcceptTcpClient(ar);
byte[] _ReceiveBuffer = new byte[8197];
System.IO.StreamWriter streamW = new System.IO.StreamWriter(_MessageClient.GetStream());
ClientDefinition newClient = new ClientDefinition();
newClient.Socket = _MessageClient.Client;
newClient.Socket.ReceiveTimeout = 7000; newClient.Socket.SendTimeout = 7000;
newClient.username = "undefined" + clients.Count;
newClient.receiveBuffer = new byte[8197];
clients.Add(newClient);
newClient.Socket.BeginReceive(newClient.receiveBuffer, 0, 8196, SocketFlags.None, new AsyncCallback(OnReceiveComplete), newClient);
_MessageListener.BeginAcceptTcpClient(new AsyncCallback(OnBeginAccept), null);
Console.WriteLine("new client accepted");
}
catch (Exception ex) { LogError(ex); }
}
static void OnReceiveComplete(IAsyncResult ar)
{
ClientDefinition fromClient = null; //Wrapper for Socket
fromClient = (ClientDefinition)ar.AsyncState;
if (fromClient == null) return;
try
{
if (!fromClient.Socket.Connected)
{
Console.WriteLine("fromclient (" + fromClient.username + ") not connected");
CloseClient(fromClient);
return;
}
int receiveLength = 0;
receiveLength = fromClient.Socket.EndReceive(ar);
if (receiveLength == 0)
{
Console.WriteLine("Receivelength == 0");
CloseClient(fromClient);
}
SocketMessage message = null;
message = Serializer.Deserialize<SocketMessage>(fromClient.receiveBuffer);
System.Array.Clear(fromClient.receiveBuffer, 0, receiveLength);
/******Here is where I handle the messages. And when doing an operation that is 'big', a client is closed.*****/
fromClient.Socket.BeginReceive(fromClient.receiveBuffer, 0, 8196, SocketFlags.None, new AsyncCallback(OnReceiveComplete), fromClient);
}
catch (Exception ex)
{
Console.WriteLine("Exception in OnReceiveComplete: " + ex.Message + ex.StackTrace + "obj: " + ex.Source);
CloseClient(fromClient);
}
static void onbeginacept(IAsyncResult ar)
{
尝试
{
TcpClient\u MessageClient=\u MessageListener.EndAcceptTcpClient(ar);
字节[]_ReceiveBuffer=新字节[8197];
System.IO.StreamWriter streamW=新的System.IO.StreamWriter(_MessageClient.GetStream());
ClientDefinition newClient=新ClientDefinition();
套接字=_MessageClient.Client;
newClient.Socket.ReceiveTimeout=7000;newClient.Socket.SendTimeout=7000;
newClient.username=“undefined”+clients.Count;
newClient.receiveBuffer=新字节[8197];
clients.Add(newClient);
newClient.Socket.BeginReceive(newClient.receiveBuffer,08196,SocketFlags.None,新异步回调(OnReceiveComplete),newClient);
_MessageListener.BeginAcceptTcpClient(新的异步回调(OnBeginAccept),null);
Console.WriteLine(“接受新客户”);
}
catch(异常ex){LogError(ex);}
}
接收完成时静态无效(IAsyncResult ar)
{
ClientDefinition fromClient=null;//套接字的包装器
fromClient=(ClientDefinition)ar.AsyncState;
if(fromClient==null)返回;
尝试
{
如果(!fromClient.Socket.Connected)
{
Console.WriteLine(“fromclient(+fromclient.username+”)未连接);
CloseClient(fromClient);
返回;
}
int receiveLength=0;
receiveLength=fromClient.Socket.EndReceive(ar);
如果(接收长度==0)
{
Console.WriteLine(“Receivelength==0”);
CloseClient(fromClient);
}
SocketMessage=null;
message=Serializer.Deserialize(fromClient.receiveBuffer);
System.Array.Clear(fromClient.receiveBuffer,0,receiveLength);
/******这里是我处理消息的地方。当执行“大”操作时,客户端关闭*****/
fromClient.Socket.BeginReceive(fromClient.receiveBuffer,0,8196,SocketFlags.None,新异步回调(OnReceiveComplete),fromClient);
}
捕获(例外情况除外)
{
Console.WriteLine(“OnReceiveComplete中的异常:+ex.Message+ex.StackTrace+”obj:+ex.Source”);
CloseClient(fromClient);
}
原因是我有一个对套接字的强引用,而不是TcpClient,当程序积累了足够的垃圾时,它会处理网络流,从而关闭底层套接字。此行为与.NET不同。通过将接受的TcpClient存储在静态列表中来解决