[英]Kicking clients from TCP server
我试图向服务器添加功能以踢特定的客户端。 但是客户端线程中的Read
函数阻塞了循环,并且客户端发送另一条消息之前,不会执行客户端的kicked命令。 所以我将其添加到服务器中客户端的线程中; (顺便说一句,我真的不明白为什么我应该把Poll
放在那儿,但是如果没有它就会抛出错误。)
if (client.Socket.Poll(10, SelectMode.SelectRead))
{
readMessageSize = client.Stream.Read(readMessage, 0, _packetSize);
}
else
{
if (client.Kicked)
{
Console.WriteLine("The client [" + client.IP + "] has been kicked.");
break;
}
Thread.Sleep(10);
continue;
}
这次,它给客户端的构造函数带来了错误(该构造函数将从Accept()
函数返回的套接字作为参数)说:“在非阻塞套接字上不允许进行该操作。” 因此,我暂时将Blocking设置为true;
public ClientSocket(Socket client)
{
_socket = client;
_socket.Blocking = true;
try
{
Stream = new NetworkStream(_socket);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
_socket.Blocking = false;
}
我还将侦听器套接字的Blocking设置为false并更改了它,因为当我尝试Abort()
侦听器线程时,它不会,因为它卡在了Accept()
。
while (Running)
{
try
{
if (_socket.Poll(10, SelectMode.SelectRead))
{
var newClientSocket = _socket.Accept();
AddClient(newClientSocket);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
StopListen();
break;
}
Thread.Sleep(250);
}
我感觉实现服务器的方式错误。 我准备好听听任何建议。 我也可以接受任何可能对我有帮助的开源项目或代码段。
关于您发布的代码:
NetworkStream
对象提供非阻塞套接字,则稍后将您分配给NetworkStream
的套接字设置为非阻塞只会造成问题。 Socket.Poll()
方法即可正确执行此操作,但请务必注意,“微秒”(用于Poll()
方法)与“毫秒”(几乎在所有地方使用)之间存在差异NET中的整数时间间隔)。 也许您真的想在Poll()
方法中只等待10微秒,但是从您的帖子中并不清楚您打算做什么,所以我想确保您知道其中的区别。 就执行此操作的正确方法而言:
NetworkStream
,所以最明显的方法是使用ReadAsync()
方法。 Socket.Shutdown()
方法,等待客户端关闭其末尾(即,您看到一个长度为0字节的接收操作)。 但是如果需要的话,您可能可以摆脱重置连接的Socket.Close()
即Socket.Close()
)。 这两种方法都会导致异步读取操作完成,从而使您可以清除客户端信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.