Newbie threading questions (data exchange + shutdown)
-
I'm writing a simple multi-threaded TCP socket server, in which a new thread is created for each incoming connection (I only have to handle few connection so this should be ok). It is something like this:
static void Main(string[] args)
{
...// Setup server socket TcpListener listener = new TcpListener(IPAddress.Any, servPort); listener.Start(); while(true) { try { // Block waiting for connection Socket clntSock = listener.AcceptSocket(); // Connection detected: launch worker thread MyProtocol protocol = new MyProtocol(); Thread thread = new Thread(new ThreadStart(protocol.HandleClient)); thread.Start(); } catch (System.IO.IOException e) { // Perform error handling ... } }
}
public class MyProtocol
{
public void HandleClient()
{
// Code to handle incoming data from client
...
}
}I have several newbie questions: 1) How can I access data living in the worker threads? I was thinking to use properties in
MyProtocol
class for this purpose, like:public class MyProtocol
{
// Value used inside HandleClient()
public int Data
{
get { return _Data; }
set { _Data = value; }
}
private int _Data;public void HandleClient() {...}
}
The main thread keeps a reference to the
MyProtocol
objects created, and uses theData
property to exchange data with the thread (with appropriate synchronization usinglock
to avoid race conditions). Is this ok? Is there any better approach? 2) Which is the correct way to shut down the connection threads? For example, if I want to close the server application, I think I should deal with terminating the connections in a correct manner. Best regards, Andrea -
I'm writing a simple multi-threaded TCP socket server, in which a new thread is created for each incoming connection (I only have to handle few connection so this should be ok). It is something like this:
static void Main(string[] args)
{
...// Setup server socket TcpListener listener = new TcpListener(IPAddress.Any, servPort); listener.Start(); while(true) { try { // Block waiting for connection Socket clntSock = listener.AcceptSocket(); // Connection detected: launch worker thread MyProtocol protocol = new MyProtocol(); Thread thread = new Thread(new ThreadStart(protocol.HandleClient)); thread.Start(); } catch (System.IO.IOException e) { // Perform error handling ... } }
}
public class MyProtocol
{
public void HandleClient()
{
// Code to handle incoming data from client
...
}
}I have several newbie questions: 1) How can I access data living in the worker threads? I was thinking to use properties in
MyProtocol
class for this purpose, like:public class MyProtocol
{
// Value used inside HandleClient()
public int Data
{
get { return _Data; }
set { _Data = value; }
}
private int _Data;public void HandleClient() {...}
}
The main thread keeps a reference to the
MyProtocol
objects created, and uses theData
property to exchange data with the thread (with appropriate synchronization usinglock
to avoid race conditions). Is this ok? Is there any better approach? 2) Which is the correct way to shut down the connection threads? For example, if I want to close the server application, I think I should deal with terminating the connections in a correct manner. Best regards, AndreaMetal76 wrote:
The main thread keeps a reference to the MyProtocol objects created, and uses the Data property to exchange data with the thread (with appropriate synchronization using lock to avoid race conditions). Is this ok? Is there any better approach?
Yeah. This would be OK.
Metal76 wrote:
Which is the correct way to shut down the connection threads?
I would add a
Stop()
method toMyProtocol
class. See the below examplevolatile bool canContinue = true;
public void HandleClient(){
while(canContinue){
......
}
}public void Stop(){
canContinue = false;
}You need to call
Stop
on all theMyProtocol
instances created. Alternatively, you can make the thread as background.MyProtocol protocol = new MyProtocol();
Thread thread = new Thread(new ThreadStart(protocol.HandleClient));
thread.IsBackground = true;
thread.Start();So it ends when the main thread ends. But the first one would be the better choice.
-
Metal76 wrote:
The main thread keeps a reference to the MyProtocol objects created, and uses the Data property to exchange data with the thread (with appropriate synchronization using lock to avoid race conditions). Is this ok? Is there any better approach?
Yeah. This would be OK.
Metal76 wrote:
Which is the correct way to shut down the connection threads?
I would add a
Stop()
method toMyProtocol
class. See the below examplevolatile bool canContinue = true;
public void HandleClient(){
while(canContinue){
......
}
}public void Stop(){
canContinue = false;
}You need to call
Stop
on all theMyProtocol
instances created. Alternatively, you can make the thread as background.MyProtocol protocol = new MyProtocol();
Thread thread = new Thread(new ThreadStart(protocol.HandleClient));
thread.IsBackground = true;
thread.Start();So it ends when the main thread ends. But the first one would be the better choice.
Hi Navaneeth, thanks for fast and really useful reply! I have an additional doubt regarding thread shutdown. At the moment, the HandleClient() is something like this:
void HandleClient()
{
...// Block until data is available from socket or client disconnected
while ((recvMsgSize = clntSock.Receive(rcvBuffer, 0, rcvBuffer.Length, SocketFlags.None)) > 0)
{
// Process received data
...
}// Client disconnected, return from function --> terminate thread
}So when shutting down the application I'd like to shutdown any active client connection and release any network resource. In order to use your solution (polling the
canContinue
flag) I think I should avoid blocking calls like the socketReceive()
one. Am I right? And can you suggest a "graceful" way to shutdown alive connections? Thanks in advance and regards, Andrea -
Hi Navaneeth, thanks for fast and really useful reply! I have an additional doubt regarding thread shutdown. At the moment, the HandleClient() is something like this:
void HandleClient()
{
...// Block until data is available from socket or client disconnected
while ((recvMsgSize = clntSock.Receive(rcvBuffer, 0, rcvBuffer.Length, SocketFlags.None)) > 0)
{
// Process received data
...
}// Client disconnected, return from function --> terminate thread
}So when shutting down the application I'd like to shutdown any active client connection and release any network resource. In order to use your solution (polling the
canContinue
flag) I think I should avoid blocking calls like the socketReceive()
one. Am I right? And can you suggest a "graceful" way to shutdown alive connections? Thanks in advance and regards, AndreaIt depends from where you are calling
Stop()
method. If it is called from main thread, you can shutdown the socket inside theStop()
method. I am not sure that this is the graceful way.Navaneeth How to use google | Ask smart questions
-
I'm writing a simple multi-threaded TCP socket server, in which a new thread is created for each incoming connection (I only have to handle few connection so this should be ok). It is something like this:
static void Main(string[] args)
{
...// Setup server socket TcpListener listener = new TcpListener(IPAddress.Any, servPort); listener.Start(); while(true) { try { // Block waiting for connection Socket clntSock = listener.AcceptSocket(); // Connection detected: launch worker thread MyProtocol protocol = new MyProtocol(); Thread thread = new Thread(new ThreadStart(protocol.HandleClient)); thread.Start(); } catch (System.IO.IOException e) { // Perform error handling ... } }
}
public class MyProtocol
{
public void HandleClient()
{
// Code to handle incoming data from client
...
}
}I have several newbie questions: 1) How can I access data living in the worker threads? I was thinking to use properties in
MyProtocol
class for this purpose, like:public class MyProtocol
{
// Value used inside HandleClient()
public int Data
{
get { return _Data; }
set { _Data = value; }
}
private int _Data;public void HandleClient() {...}
}
The main thread keeps a reference to the
MyProtocol
objects created, and uses theData
property to exchange data with the thread (with appropriate synchronization usinglock
to avoid race conditions). Is this ok? Is there any better approach? 2) Which is the correct way to shut down the connection threads? For example, if I want to close the server application, I think I should deal with terminating the connections in a correct manner. Best regards, AndreaHi Andrea, You should use one of the asynchronous patterns available on
Socket
: eitherBeginReceive
or the newReceiveAsync
. It is not necessary ( or beneficial ) to create a thread for each connection. BeginReceive[^] ReceiveAsync[^], good example[^] In answer to your questions: 1) To pass the received data to your main thread,MyProtocol
should publish an event which it raises when a whole useful "message" has been received. 2) To handle application shutdown, keep a list of open sockets inMyProtocol
and expose a method that, for each socket, sends any command messages required by the protocol to end the connection, and then callsShutdown
andDispose
on theSocket
. Nick---------------------------------- Be excellent to each other :)
-
Hi Andrea, You should use one of the asynchronous patterns available on
Socket
: eitherBeginReceive
or the newReceiveAsync
. It is not necessary ( or beneficial ) to create a thread for each connection. BeginReceive[^] ReceiveAsync[^], good example[^] In answer to your questions: 1) To pass the received data to your main thread,MyProtocol
should publish an event which it raises when a whole useful "message" has been received. 2) To handle application shutdown, keep a list of open sockets inMyProtocol
and expose a method that, for each socket, sends any command messages required by the protocol to end the connection, and then callsShutdown
andDispose
on theSocket
. Nick---------------------------------- Be excellent to each other :)