C#异步套接字,服务器过载时丢失数据包
我使用.NETSocket编写了一个异步服务器,当这个服务器过载时(例如接收大量数据,文件),服务器不会接收到所有数据包 如果我增加缓冲区的长度,我会收到更多的数据,但不是所有的数据包 有人能解决我的问题吗 我的服务器的代码是:C#异步套接字,服务器过载时丢失数据包,c#,.net,sockets,asyncsocket,C#,.net,Sockets,Asyncsocket,我使用.NETSocket编写了一个异步服务器,当这个服务器过载时(例如接收大量数据,文件),服务器不会接收到所有数据包 如果我增加缓冲区的长度,我会收到更多的数据,但不是所有的数据包 有人能解决我的问题吗 我的服务器的代码是: class ServerFile { #region Delegate private delegate void Method(ConnectionInfoFile Infos, Object Content); #endregion
class ServerFile
{
#region Delegate
private delegate void Method(ConnectionInfoFile Infos, Object Content);
#endregion
#region Fields
private Int32 Port;
private Socket ServerSocket = null;
private List<ConnectionInfoFile> Connections = new List<ConnectionInfoFile>();
private Dictionary<Command, Method> Map = new Dictionary<Command, Method>();
#endregion
#region Constructor
public ServerFile(Int32 Port)
{
this.Port = Port;
this.Map[Command.Server_User_Login] = this.Login;
}
#endregion
#region Methods - Login
private void Login(ConnectionInfoFile Client, Object Content)
{
Client.Id = (Int32)Content;
Console.WriteLine("[" + DateTime.Now.ToShortTimeString() + "] - " + this.GetType().Name.Insert(6, " ") + " - The client is now authentified as '" + Client.Id + "'.");
}
#endregion
#region Methods - Receive
private void ReceiveCallback(IAsyncResult Result)
{
ConnectionInfoFile Connection = (ConnectionInfoFile)Result.AsyncState;
try
{
Int32 BytesRead = Connection.Socket.EndReceive(Result);
if (BytesRead != 0)
{
Byte[] Message = (new MemoryStream(Connection.AsyncBuffer, 0, BytesRead)).ToArray();
Connection.Append(Message);
Packet Packet;
while ((Packet = Connection.TryParseBuffer()) != null)
{
Console.WriteLine("[" + DateTime.Now.ToShortTimeString() + "] - " + this.GetType().Name.Insert(6, " ") + " - Command received : " + Packet.Command.ToString());
if (Packet.Recipient == 0)
{
if (this.Map.ContainsKey(Packet.Command))
this.Map[Packet.Command](Connection, Packet.Content);
}
else
{
foreach (ConnectionInfoFile Item in this.Connections)
{
if (Item.Id == Packet.Recipient)
{
Byte[] Buffer = Packet.Serialize(Connection.Id, Packet.Command, Packet.Content);
this.Send(Item, Buffer);
}
}
}
}
Connection.Socket.BeginReceive(Connection.AsyncBuffer, 0, Connection.AsyncBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), Connection);
}
else
this.CloseConnection(Connection);
}
catch (SocketException E)
{
CloseConnection(Connection);
Console.WriteLine("[" + DateTime.Now.ToShortTimeString() + "] - " + this.GetType().Name.Insert(6, " ") + " - Receive socket exception : " + E.SocketErrorCode);
}
catch (Exception E)
{
CloseConnection(Connection);
Console.WriteLine("[" + DateTime.Now.ToShortTimeString() + "] - " + this.GetType().Name.Insert(6, " ") + " - Receive exception : "+ E.Message);
}
}
#endregion
#region Methods - CloseConnection
private void CloseConnection(ConnectionInfoFile Connection)
{
Connection.Socket.Close();
Console.WriteLine("[" + DateTime.Now.ToShortTimeString() + "] - " + this.GetType().Name.Insert(6, " ") + " - The user " + Connection.Id + " has been disconnected !");
lock (this.Connections)
{
this.Connections.Remove(Connection);
}
}
#endregion
#region Methods - Send
protected void Send(IConnectionInfo Connection, Byte[] Buffer)
{
Connection.Socket.BeginSend(Buffer, 0, Buffer.Length, 0, new AsyncCallback(SendCallback), Connection);
}
private static void SendCallback(IAsyncResult Result)
{
try
{
IConnectionInfo Connection = (IConnectionInfo)Result.AsyncState;
Int32 BytesSent = Connection.Socket.EndSend(Result);
Console.WriteLine("[" + DateTime.Now.ToShortTimeString() + "] - " + typeof(ServerFile).Name.Insert(6, " ") + " - Sent " + BytesSent + " bytes " + Connection.Id.ToString() + ".");
}
catch (Exception E)
{
Console.WriteLine("[" + DateTime.Now.ToShortTimeString() + "] - " + typeof(ServerFile).GetType().Name.Insert(6, " ") + " - Exception : " + E.ToString());
}
}
#endregion
#region Methods - Stop
public void Stop()
{
this.ServerSocket.Close();
this.ServerSocket = null;
}
#endregion
#region Methods - Start
public void Start()
{
Console.WriteLine("[" + DateTime.Now.ToShortTimeString() + "] - " + this.GetType().Name.Insert(6, " ") + " - Start listening on port " + this.Port + "...");
this.ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
this.ServerSocket.Bind(new IPEndPoint(IPAddress.Any, this.Port));
this.ServerSocket.Listen((Int32)SocketOptionName.MaxConnections);
for (Int32 i = 0; i < 5; i++)
this.ServerSocket.BeginAccept(new AsyncCallback(this.AcceptCallback), this.ServerSocket);
}
#endregion
#region Methods - Accept
private void AcceptCallback(IAsyncResult Result)
{
ConnectionInfoFile Connection = new ConnectionInfoFile();
Socket Socket = (Socket)Result.AsyncState;
try
{
Connection.Socket = Socket.EndAccept(Result);
Connection.ConnectionDate = DateTime.Now;
Console.WriteLine("[" + DateTime.Now.ToShortTimeString() + "] - " + this.GetType().Name.Insert(6, " ") + " - A new client has been registered");
lock (this.Connections)
{
this.Connections.Add(Connection);
}
Connection.Socket.BeginReceive(Connection.AsyncBuffer, 0, Connection.AsyncBuffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), Connection);
}
catch (SocketException E)
{
this.CloseConnection(Connection);
Console.WriteLine("[" + DateTime.Now.ToShortTimeString() + "] - " + this.GetType().Name.Insert(6, " ") + " - Accept socket exception: " + E.SocketErrorCode);
}
catch (Exception E)
{
this.CloseConnection(Connection);
Console.WriteLine("[" + DateTime.Now.ToShortTimeString() + "] - " + this.GetType().Name.Insert(6, " ") + " - Accept exception: " + E.Message);
}
Socket.BeginAccept(new AsyncCallback(AcceptCallback), Result.AsyncState);
}
#endregion
}
class服务器文件
{
#地区代表
私有委托无效方法(ConnectionInfo文件信息、对象内容);
#端区
#区域字段
专用Int32端口;
私有套接字ServerSocket=null;
私有列表连接=新列表();
私有字典映射=新字典();
#端区
#区域构造函数
公共服务器文件(Int32端口)
{
this.Port=Port;
this.Map[Command.Server\u User\u Login]=this.Login;
}
#端区
#区域方法-登录
私有无效登录(ConnectionInfo客户端,对象内容)
{
Client.Id=(Int32)内容;
Console.WriteLine(“[”+DateTime.Now.ToShortTimeString()+”]-“+this.GetType().Name.Insert(6)”+”-客户端现在被身份验证为“+client.Id+”;
}
#端区
#区域方法-接收
私有void ReceiveCallback(IAsyncResult结果)
{
ConnectionInfo文件连接=(ConnectionInfo文件)Result.AsyncState;
尝试
{
Int32 BytesRead=Connection.Socket.EndReceive(结果);
如果(字节读取!=0)
{
字节[]消息=(新内存流(Connection.AsyncBuffer,0,BytesRead)).ToArray();
连接。追加(消息);
数据包;
while((Packet=Connection.TryParseBuffer())!=null)
{
Console.WriteLine(“[”+DateTime.Now.ToShortTimeString()+”]-“+this.GetType().Name.Insert(6)”+”-收到命令:“+Packet.Command.ToString());
if(Packet.Recipient==0)
{
if(this.Map.ContainsKey(Packet.Command))
this.Map[Packet.Command](连接,Packet.Content);
}
其他的
{
foreach(此.Connections中的ConnectionInfo文件项)
{
if(Item.Id==Packet.Recipient)
{
Byte[]Buffer=Packet.Serialize(Connection.Id、Packet.Command、Packet.Content);
发送(项目、缓冲区);
}
}
}
}
Connection.Socket.BeginReceive(Connection.AsyncBuffer,0,Connection.AsyncBuffer.Length,SocketFlags.None,新建异步回调(ReceiveCallback),连接);
}
其他的
这个。闭合连接(连接);
}
捕获(SocketException E)
{
闭合连接(连接);
Console.WriteLine(“[”+DateTime.Now.ToSortTimeString()+”]-“+this.GetType().Name.Insert(6)”+“-接收套接字异常:“+E.SocketErrorCode”);
}
捕获(例外E)
{
闭合连接(连接);
Console.WriteLine(“[”+DateTime.Now.ToSortTimeString()+”]-“+this.GetType().Name.Insert(6)”+”-接收异常:“+E.Message”);
}
}
#端区
#区域方法-紧密连接
私有void CloseConnection(ConnectionInfo文件连接)
{
Connection.Socket.Close();
Console.WriteLine(“[”+DateTime.Now.ToSortTimeString()+”]-“+this.GetType().Name.Insert(6)”+”-用户“+Connection.Id+”已断开连接!”);
锁(此。连接)
{
此。连接。移除(连接);
}
}
#端区
#区域方法-发送
受保护的无效发送(IConnectionInfo连接,字节[]缓冲区)
{
Connection.Socket.BeginSend(Buffer,0,Buffer.Length,0,新的异步回调(SendCallback),Connection);
}
私有静态void SendCallback(IAsyncResult结果)
{
尝试
{
IConnectionInfo连接=(IConnectionInfo)Result.AsyncState;
Int32 BytesSent=Connection.Socket.EndSend(结果);
Console.WriteLine(“[”+DateTime.Now.ToSortTimeString()+”]-“+typeof(ServerFile).Name.Insert(6“”+”)-Sent“+BytesSent+”bytes”+Connection.Id.ToString()+”);
}
捕获(例外E)
{
Console.WriteLine(“[”+DateTime.Now.ToSortTimeString()+”]-“+typeof(ServerFile.GetType().Name.Insert(6)”+”-异常:“+E.ToString());
}
}
#端区
#区域方法-停止
公共停车场()
{
这个.ServerSocket.Close();
this.ServerSocket=null;
}
#端区
#区域方法-开始
公开作废开始()
{
Console.WriteLine(“[”+DateTime.Now.ToShortTimeString()+”]-“+this.GetType().Name.Insert(6)”+”-开始侦听端口“+this.port+”);
this.ServerSocket=新套接字(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
this.ServerSocket.Bind(新的IPEndPoint(IPAddress.Any,this.Port));
this.ServerSocket.Listen((Int32)SocketOptionName.MaxConnections);
对于(Int32 i=0;i<5;i++)
this.ServerSocket.beginacept(新的异步回调(this.AcceptCallback)、this.ServerSocket);
}
#端区
#区域方法-接受
私有void AcceptCallback(IAsyncResult结果)
{
ConnectionInfo文件连接=新建ConnectionInfo文件();
套接字套接字=(套接字)Result.AsyncState;
尝试
{
Connection.Socket=Socket.EndAccept(结果);
Connection.ConnectionDate=DateTime.Now;
孔索