[英]Kicking clients from TCP server
I tried to add a functionality to my server to kick specific clients. 我试图向服务器添加功能以踢特定的客户端。 But Read
function in client's thread is blocking the loop and client's kicked command won't be executed until client sends an another message. 但是客户端线程中的Read
函数阻塞了循环,并且客户端发送另一条消息之前,不会执行客户端的kicked命令。 So I added this to client's thread in server; 所以我将其添加到服务器中客户端的线程中; (By the way, I can't really understand why I should put Poll
there but it throws an error without it.) (顺便说一句,我真的不明白为什么我应该把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;
}
This time, it gives an error on client's constructor (this constructor takes the socket that returns from Accept()
function as parameter) says: "The operation is not allowed on a non-blocking Socket.". 这次,它给客户端的构造函数带来了错误(该构造函数将从Accept()
函数返回的套接字作为参数)说:“在非阻塞套接字上不允许进行该操作。” So, I set Blocking true temporarily like this; 因此,我暂时将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;
}
I also set listener socket's Blocking to false and changed it because when I tried to Abort()
listener thread it won't, because it's stucked at Accept()
. 我还将侦听器套接字的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);
}
I feel like I'm going a wrong way implemeting the server. 我感觉实现服务器的方式错误。 I'm ready to listen any advice. 我准备好听听任何建议。 I can also accept any open source projects or code snippets which might help me with this. 我也可以接受任何可能对我有帮助的开源项目或代码段。
With respect to the code you posted: 关于您发布的代码:
NetworkStream
object, setting a socket you've given to a NetworkStream
to non-blocking later is just going to cause problems. 如果.NET不想为NetworkStream
对象提供非阻塞套接字,则稍后将您分配给NetworkStream
的套接字设置为非阻塞只会造成问题。 Socket.Poll()
method to do this correctly, but it's very important to note that there's a difference between "microseconds" (used in the Poll()
method) and "milliseconds" (used almost everywhere else in .NET for integer time intervals). 您无需使用Socket.Poll()
方法即可正确执行此操作,但请务必注意,“微秒”(用于Poll()
方法)与“毫秒”(几乎在所有地方使用)之间存在差异NET中的整数时间间隔)。 Maybe you really mean to wait only 10 microseconds in the Poll()
method, but it's not entirely clear from your post what you meant to do, so I want to make sure you're aware of the difference. 也许您真的想在Poll()
方法中只等待10微秒,但是从您的帖子中并不清楚您打算做什么,所以我想确保您知道其中的区别。 As far as the right way to do this goes: 就执行此操作的正确方法而言:
NetworkStream
, the most obvious approach would be to use the ReadAsync()
method. 由于您使用的是NetworkStream
,所以最明显的方法是使用ReadAsync()
方法。 Socket.Shutdown()
method, waiting for the client to close its end (ie you see a receive operation complete with 0-byte length). 理想情况下,您将使用一个正常的关闭来“终止”客户端,即调用Socket.Shutdown()
方法,等待客户端关闭其末尾(即,您看到一个长度为0字节的接收操作)。 But you can probably get away with resetting the connection if you must (ie Socket.Close()
). 但是如果需要的话,您可能可以摆脱重置连接的Socket.Close()
即Socket.Close()
)。 Either will cause the asynchronous read operation to complete, allowing you to clean up the client information. 这两种方法都会导致异步读取操作完成,从而使您可以清除客户端信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.