in server -(multi)client application [TCP]. I use Socket, NetworkStream, StreamReader and StreamWriter for each client i Accept in the server .. so i have couple of questions :
Thread thAccept = new Thread(acceptClient);
Thread thJob;
private void acceptClient()
{
while (true)
{
Socket client = server.Accept();
Console.WriteLine(client.RemoteEndPoint+" has connected");
StreamReader reader = new StreamReader(new NetworkStream(client));
//is it ok to create an instance NetworkStream like this or i will have to dispose it later?
thJob = new Thread(Job);
thJob.Start(reader);
}
}
private void Job(object o)
{
StreamReader reader = (Socket)o;
try
{
string cmd = null;
while ((cmd = reader.ReadLine()) != null)
{
//(BLA BLA..)
}
}
catch
{
Console.WriteLine("Disconnected by catch");
}
finally
{
Console.WriteLine("Finally Done.");
reader.Dispose();
}
}
is that code fine to dispose all (needed to be disposed) objects?
This is not a duplicate.
Your code differs from the linked duplicate because in your code, the IDisposable
is handed off to another thread.
The general rule is that if you create an object that implements IDisposable
, then you're responsible for calling Dispose
on it when you're finished with it. When possible, that should be done in a using
block, to ensure that Dispose
is always called. In your case, your code is not finished with the object until the other thread is exited. In that thread, you correctly call Dispose
in the finally
block.
If you had called Dispose
on the NetworkStream
, then it would have closed the StreamReader
as well, which would defeat your purpose. I suspect it would be the same thing if you had called Dispose
on the Socket
. As such, your code is correct as-is.
The object on the client side has no relationship with the object on the server side, except through TCP/IP. The fact that the client may call Dispose
on its socket doesn't mean that the server has to call Dispose
on its socket. However, once the server is finished reading data from the socket, and the connection is closed, the server-side socket should be Disposed
. I don't know for certain, but I believe that when the StreamReader
is disposed, the underlying NetworkStream
will be disposed, which should call Dispose
on the socket from which the stream was created.
Your code is fine, except for some unrelated issues: you don't need to set cmd
to null
, since you're going to set the value in the next statement. Also, you should not use an empty catch
block like that. You have no idea what exception was thrown, but you will ignore it anyway, without even logging or displaying the exception. At the least, you should do
catch (Exception ex)
{
Console.WriteLine("Disconnected by exception " + ex.ToString());
}
finally
{
Console.WriteLine("Finally Done.");
reader.Dispose();
}