我有一个接受/恢复的服务器并异步发送到客户端连接 我正在使用Tcp。
接受后,所有连接都会保存到列表中:
List<Socket> clientConnections = new List<Socket>();
如何优雅地断开所有客户端?
请注意我不是要检测客户端断开连接。相反,我想强迫客户断开连接。
我的代码结构:
class ServerListener
{
List<Socket> clientConnections = new List<Socket>();
Socket ServerSocket;
public ServerListener(IPAddress IP, int Port)
{
ServerSocket = new Socket(IP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
ServerSocket.Bind(new IPEndPoint(IP, Port));
ServerSocket.Listen(10);
Program.mainForm.changeStatus(frmServer.status.online);
Program.mainForm.displayIP(((IPEndPoint)ServerSocket.LocalEndPoint).Address.ToString());
try
{
ServerSocket.BeginAccept(new AsyncCallback(AcceptCallBack), null);
}
catch (Exception)
{
}
}
void AcceptCallBack(IAsyncResult AR)
{
try
{
Socket client = ServerSocket.EndAccept(AR);
clientConnections.Add(client);
client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(RecieveCallback), client);
ServerSocket.BeginAccept(new AsyncCallback(AcceptCallBack), null);
}
catch (Exception)
{
}
}
void RecieveCallback(IAsyncResult AR)
{
Socket client = (Socket)AR.AsyncState;
int len = client.EndReceive(AR);
byte[] tempBuffer = new byte[len];
Array.Copy(buffer, tempBuffer, len);
string request = Encoding.ASCII.GetString(tempBuffer);
try
{
byte[] sendBuffer = HandleRequest(request);
client.BeginSend(sendBuffer, 0, sendBuffer.Length, SocketFlags.None, new AsyncCallback(SendCallback), client); // send data
}
catch (Exception)
{
client.Close();
clientConnections.Remove(client);
DisplayClientRequestInfo("User Disconnected.");
}
}
void SendCallback(IAsyncResult AR)
{
Socket client = (Socket)AR.AsyncState;
client.EndSend(AR);
client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(RecieveCallback), client);
}
// listening for changes
public delegate void textRecievedEventHandler(object sender, EventArgs e, string message);
public event textRecievedEventHandler messageChanged;
protected virtual void DisplayClientRequestInfo(string message)
{
if (messageChanged != null)
{
messageChanged(this, EventArgs.Empty, message);
}
}
// handling requests
byte[] HandleRequest(string request)
{
string response = string.Empty;
// Create the response...
return Encoding.ASCII.GetBytes(response);
}
public void Stop()
{
try
{
// disconnect Here
ServerSocket.Dispose();
foreach (Socket s in clientConnections)
{
KickUser(s);
}
}
catch (SocketException)
{
}
catch (Exception e)
{
DisplayClientRequestInfo(e.Message);
}
}
void KickUser(Socket socket)
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
}
因此,当用户单击“停止服务器”按钮时,它将运行:
sl.Stop();
其中sl是ServerListener的一个实例。
连接客户端并停止服务器时,出现以下错误:
System.dll
其他信息:无法访问已处置的对象。
我认为这是因为连接异步。同样在客户端,socket.Connected
为true
。意思是它仍然认为它连接到服务器。
那么从服务器安全地踢用户的正确方法是什么?