Note that there are some explanatory texts on larger screens.

plurals
  1. POMultiple Threads to the same TCP Socket
    primarykey
    data
    text
    <p>I am a .NET Developer and am new to Socket Programming.</p> <p>I wrote a program which sends some data to the client using a TCP Socket using .NET Socket Library.</p> <p>The client requires a custom Keep Alive Message every 40 secs to keep the connection alive.</p> <p>So, I wrote main program that establishes a connection with the client. With-in this main program, I create a thread and pass the instance of Socket Class that was created earlier. This thread is responsible for sending the keep alive messages to the client while the main thread is responsible for sending the data.</p> <p>It all works good. But if for some reason socket connection is time out, the program will never recover? I put the logic for both the threads to exit and new connnection to be established but it will always give an error - ' The connection with the host is aborted' or something similar.</p> <p>Am i doing something wrong?</p> <p>I need to have two threads connected to the same socket. One thread is responsible for sending the data and other is responsible for sending the keep alive messages. What should be the best approach for this?</p> <p>No, I am not trying to use the same socket. I break away from the for loop and clntSock.close()...</p> <p>Here is the code :</p> <p>I have mainThread that calls handleClient. handleClient Creates another thread.</p> <pre><code>class DispatchLoop { ILogger logger; TcpListener listener; IProtocolFactory protoFactory; public DispatchLoop(TcpListener listener, ILogger logger, IProtocolFactory protoFactory) { this.logger = logger; this.listener = listener; this.protoFactory = protoFactory; } public void mainThread() { // Run forever, accepting and handling each connection for (; ; ) { try { Socket clntSock = listener.AcceptSocket(); // Block waiting for connection PoolDispatcher._stopper.Reset(); clntSock.ReceiveTimeout = 10000; IProtocol protocol = protoFactory.createProtocol(clntSock, logger); protocol.handleClient(); } catch (SocketException se) { logger.writeEntry("(Run Dispatcher) Exception = " + se.Message); } } } } public void handleClient() { entry.Add("Main Thread Entered : Client address and Port = " + clntSock.RemoteEndPoint + ", Thread Number = " + Thread.CurrentThread.GetHashCode()); //Kick Starting Keep Alive Thread KeepAlive ka = new KeepAlive(clntSock, logger); Thread thread = new Thread(new ThreadStart(ka.SendKeepAlive)); thread.Start(); try { int recvMsgSize; // Size of received message byte[] rcvBuffer = new byte[BUFSIZE]; // Receive buffer byte[] messageBuffer = new byte[1024]; XDocument _messageXDoc; FlightInfoExtended _flightInfoExtended; try { LogEntry(entry); for (; ; ) { try { //Read from the Queue var _queue = new IBMQueue(); var message = _queue.ReceiveMessage(); if (message.Length &gt; 0) { entry.Add("Sending the GOS Message to the client : " + message); messageBuffer = Encoding.ASCII.GetBytes(message); if (clntSock.Connected) { clntSock.Send(messageBuffer, 0, messageBuffer.Length, SocketFlags.None); recvMsgSize = clntSock.Receive(rcvBuffer, 0, rcvBuffer.Length, SocketFlags.None); SaveGOSMessage(_auditMessage); } else { PoolDispatcher._stopper.Set(); LogFailureStatus("No Socket Connection"); Thread.Sleep(30000); break; } } } catch (SocketException se) { PoolDispatcher._stopper.Set(); LogFailureStatus(se.Message); Thread.Sleep(30000); break; } catch (Exception e) { } LogEntry(entry); } } catch (Exception se) { entry.Add(String.Format("{0}: {1}", se.Source, se.Message)); } } catch (Exception se) { entry.Add(String.Format("{0}: {1}", se.Source, se.Message)); } clntSock.Close(); logger.writeEntry(entry); } public class KeepAlive { ArrayList entry; private ILogger logger; private Socket clntSock; public const int BUFSIZE = 1024; public KeepAlive(Socket clntSock, ILogger logger) { this.logger = logger; this.clntSock = clntSock; entry = new ArrayList(); } void LogEntry(ArrayList _entry) { logger.writeEntry(_entry); entry.Clear(); } public void SendKeepAlive() { entry.Add("Keep Alive Thread Entered : Client address and Port = " + clntSock.RemoteEndPoint + ", Thread Number = " + Thread.CurrentThread.GetHashCode()); var message= "Some Keep Alive Message"; try { byte[] messageBuffer = new byte[1024]; LogEntry(entry); for (; ; ) { //Check if main thread died if ( PoolDispatcher._stopper.WaitOne(100, false)) { break; } if (clntSock.Connected) { entry.Add("Sending the Keep Alive Message... " + message); messageBuffer = Encoding.ASCII.GetBytes(message); clntSock.Send(messageBuffer, 0, messageBuffer.Length, SocketFlags.None); } else { entry.Add("Socket Connection is not active. Keep Alive not sent"); break; } LogEntry(entry); Thread.Sleep(30000); } } catch (SocketException se) { entry.Add(String.Format("{0}: {1}", se.ErrorCode, se.Message)); } catch (ObjectDisposedException ode) { entry.Add("Connection to the socket lost. Child Thread Aborted"); } LogEntry(entry); } } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload