Jump to content

Detect TCP Client Disconnect from server


Recommended Posts

Hello, I am unable to detect a client disconnect from my Autoit Server. 

I thought that maybe TCPRecv would throw an error of "-2" if the client disconnected, but it doesn't seem to do so.

Here is a part of the code:

 

MsgBox(0, "Version", @AutoItVersion)
MsgBox($MB_OK, "Title", $Server, 10)
OnAutoItExitRegister("OnAutoItExit")

TCPStartup()
$MainSocket = TCPListen($Server, $Port, $MaxConnection)
If $MainSocket = -1 Then Exit MsgBox(16, "Error", "Unable to intialize socket.")
While 1

    If $ConnectedSocket = -1 Then
        $ConnectedSocket = TCPAccept($MainSocket)
         _DebugOut("TCPAccept return: " & $ConnectedSocket )
        If $ConnectedSocket <> -1 Then
     ; Someone Connected
     _DebugOut("Someone Connected")
            TCPSend($ConnectedSocket, "Connected!")
        EndIf
     EndIf

    If $ConnectedSocket <> -1 Then
         $Data = TCPRecv($ConnectedSocket, $MaxLength)
         _DebugOut("Error is: " & @error)
            Switch @error
            Case 0 ;no error.  process normally
                if StringLen($Data) <> 0 Then


                EndIf
            Case -1 ;if using AutoIt 3.3.10.0 or higher, this error is actually "no data received", not an error.  This error code does not exist in previous versions of AutoIt.
                $Data = ""
            Case Else ;TCP error.  disconnect
               TCPCloseSocket($ConnectedSocket)
               $ConnectedSocket = -1
               $Data = ""
            EndSwitch
      EndIf

         _DebugOut("Connected Socket: " & $ConnectedSocket)

WEnd

Link to comment
Share on other sites

the error returned by the @error macro refers to the function that was just performed, and is reset at the beginning of each function. In your code the "Switch @error" line checks the error code returned by the _DebugOut() function and not the one previously returned by the TCPRecv() function. You should instead save the code returned by @error in a variable immediately after TCPRecv() and use this variable in subsequent checks. Something like:

...

If $ConnectedSocket <> -1 Then
    $Data = TCPRecv($ConnectedSocket, $MaxLength)
    $iError = @error ; save the error returned by the TCPRecv function
    _DebugOut("Error is: " & $iError)
    Switch $iError

...

 

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

  • 3 weeks later...
On 10/22/2019 at 10:07 AM, Chimp said:

the error returned by the @error macro refers to the function that was just performed, and is reset at the beginning of each function. In your code the "Switch @error" line checks the error code returned by the _DebugOut() function and not the one previously returned by the TCPRecv() function. You should instead save the code returned by @error in a variable immediately after TCPRecv() and use this variable in subsequent checks. Something like:

...

If $ConnectedSocket <> -1 Then
    $Data = TCPRecv($ConnectedSocket, $MaxLength)
    $iError = @error ; save the error returned by the TCPRecv function
    _DebugOut("Error is: " & $iError)
    Switch $iError

...

 

I still get no error except for 0. I am trying from both putty connecting to myself through 127.0.0.1, and using another device. 

Link to comment
Share on other sites

Tested it on my own TCP client/server and in case of disconnection I get @error 10054.

Hard to help you with only a part of receiver and no sender...

ps.  when you post code, please use this tool.

Link to comment
Share on other sites

10 minutes ago, Nine said:

Tested it on my own TCP client/server and in case of disconnection I get @error 10054.

Hard to help you with only a part of receiver and no sender...

ps.  when you post code, please use this tool.

I am testing with Putty etc, and it is honestly most of the code. 

The rest of the code is just this:

 

Func OnAutoItExit()
    If $ConnectedSocket <> - 1 Then
        TCPSend($ConnectedSocket, "~bye")
        TCPCloseSocket($ConnectedSocket)
    EndIf
    If $MainSocket <> -1 Then TCPCloseSocket($MainSocket)
    TCPShutdown()
EndFunc

 

I just now downgraded to 3.8.1.1, changed the code a bit, and now it works.

 

#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.3.14.5
 Author:         myName

 Script Function:
    Template AutoIt script.

#ce ----------------------------------------------------------------------------
;#include <MsgBoxConstants.au3>
#include <Inet.au3>
#include <Debug.au3>

; Script Start - Add your code below here
Global $Commands[9]
Global $MainSocket = -1
Global $ConnectedSocket = -1
Local $MaxConnection = 1; Maximum Amount Of Concurrent Connections
Local $MaxLength = 512; Maximum Length Of String
Local $Port = 51773; Port Number
;Local $Server = @IPAddress1; Server IpAddress
Local $Server = "0.0.0.0"; Server IpAddress
_DebugSetup()

MsgBox(0, "Version", @AutoItVersion)
;MsgBox($MB_OK, "Title", $Server, 10)
OnAutoItExitRegister("OnAutoItExit")

TCPStartup()
$MainSocket = TCPListen($Server, $Port, $MaxConnection)
If $MainSocket = -1 or $MainSocket = 0 Then Exit MsgBox(16, "Error", "Unable to intialize socket.")
While 1

    If $ConnectedSocket = -1 Then
        $ConnectedSocket = TCPAccept($MainSocket)
         _DebugOut("TCPAccept return: " & $ConnectedSocket )
        If $ConnectedSocket <> -1 Then
     ; Someone Connected
     _DebugOut("Someone Connected")
            TCPSend($ConnectedSocket, "Connected!")
        EndIf
     EndIf

    If $ConnectedSocket <> -1 Then
         ;Sleep(500)
         $Data = TCPRecv($ConnectedSocket, $MaxLength)
         $iError = @error
         If $iError = -1 Then
               $Data = ""
               TCPCloseSocket($ConnectedSocket)
               $ConnectedSocket = -1
            Else
               
               If StringLen($Data) > 0 Then
                  
            MsgBox(0, "Test", $Data, 10)
            
               EndIf

         EndIf
      EndIf

         _DebugOut("Connected Socket: " & $ConnectedSocket)

WEnd
Func OnAutoItExit()
    If $ConnectedSocket <> - 1 Then
        TCPSend($ConnectedSocket, "~bye")
        TCPCloseSocket($ConnectedSocket)
    EndIf
    If $MainSocket <> -1 Then TCPCloseSocket($MainSocket)
    TCPShutdown()
EndFunc

 

Edited by AutoDavid
Link to comment
Share on other sites

On 11/7/2019 at 7:44 PM, Nine said:

idk, I get either an @error if there is an interrupted connection, and @extended  = 1 if the socket gets closed without sending data...

Extended is a bit slow, but it works :) @error does nothing still. Thanks.

Edited by AutoDavid
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...