TCP Socket Flush Main Thread lockup Question

I have an interesting scenario that I am trying to protect against that I can’t seem to figure out yet.

Setup:

  1. This is a Console App (MacOS/Linux)
  2. TCP Socket running in the Main Thread
  3. Console App Socket connects just fine to server and Console Socket.write/socket.flush with no issues.
  4. Negotiates a bunch of framing message types that I created … No issues.

Scenario I am trying to protect against:

  1. Console App connects
  2. Console App Connects and BEGINs negotiation of my TCP based protocol (socket.write/socket.flush)
  3. I shutdown my server simulating network/server issues while in mid stream protocol negotiation (very quick after connection)
  4. Console App now attempts to send a socket.write and then a socket.flush and its locks up everything (I also have an additional thread running for heartbeats which is locked also)
  5. The Console app as it is attempting the final socket.flush prior to lockup I do notice that the disconnect is so fast that the Socket.ISConnected still is True so that is why it still attempts the flush.

Has anyone had this type of scenario to prevent against?

Any thoughts would be appreciated (I can post code but I wanted to start with the theory of my issue first).

Thanks!

Two questions:

  1. I assume you’re using the client socket asynchronously. Correct?

  2. In the main event loop of the client console app, are you polling the socket?

You won’t always know about the disconnect right when it happens. The whole point of TCP is to be a little robust over temporary network failures, so unless the server explicitly tells the client “I am disconnecting now”, the client will keep trying for a little while.

[quote=95278:@Brad Hutchings]Two questions:

  1. I assume you’re using the client socket asynchronously. Correct?

  2. In the main event loop of the client console app, are you polling the socket?

You won’t always know about the disconnect right when it happens. The whole point of TCP is to be a little robust over temporary network failures, so unless the server explicitly tells the client “I am disconnecting now”, the client will keep trying for a little while.[/quote]
Brad you may have pointed out my flaw.

I am polling in the main thread once. Then I am not polling again unless I make an official Reconnect.

App.Run snippet.

    Do
      EVIP_Connect.Poll
    Loop until EVIP_Connect.IsConnected = False or Microseconds - EVIP_Connect.EVIP_Start_Timer > 5000000
    
    if EVIP_Connect.IsConnected = False Then
      mSystemLog("1","(EVIP)","EVIP Connection Failed to " + EVIP_Connect.Address)
      EVIP_Connect.Disconnect
      Failed_EVIP_Connection = True
      mSystemLog("1","(EVIP)","EVIP retrying connection to " + EVIP_Connect.Address)
      mSystemLog("1","(EVIP)","Waiting 3 seconds before next retry attempt")
      App.DoEvents(3000) // Wait 3 Seconds in Between ReConnect Attempts
    End if

I am now thinking I will need to get a timer to “poll” my socket while I am connected. Is that what you were referring on your response above Brad?

Thanks again!

Brad thank you! That is exactly what I needed :slight_smile:

I added a “Socket.poll” write before I flush in my method and it works like a champ to recognize the down tcp connection.Thanks again!!

You’re welcome. I tossed a dart. You landed it.

:wink: Talk about lobbing up a softball :slight_smile: hehe Maybe on twitter :slight_smile: