Reputation: 444
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. 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.)
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.". So, I set Blocking true temporarily like this;
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()
.
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.
Upvotes: 0
Views: 1182
Reputation: 70671
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.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). 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.As far as the right way to do this goes:
NetworkStream
, the most obvious approach would be to use the ReadAsync()
method.Socket.Shutdown()
method, waiting for the client to close its end (i.e. you see a receive operation complete with 0-byte length). But you can probably get away with resetting the connection if you must (i.e. Socket.Close()
). Either will cause the asynchronous read operation to complete, allowing you to clean up the client information.Upvotes: 1