BinaryBrother

TCPRecv = @error on empty String.

4 posts in this topic

#1 ·  Posted (edited)

Have we came any further since >this post pretty much pointed out that receiving empty data, now caused TCPRecv to return an error?

By everything that I've read, we can't determine if a socket has been disconnected by the output or error output of TCPRecv.

Basically... Let me start over. ^_^

I am having an issue determining when a socket has been lost or disconnected, as TCPRecv returns @error = -1 on an empty return. Simply, how do I determine if a socket has been terminated?

A theoritical reproducer is to TCPConnect to a telnet server and throw TCPRecv in a loop waiting for responses, after the server sends the initial prompts asking for authentication, the TCPRecv immediately starts throwing @errors, despite still having an active socket. Disconnecting, at this point still throws '-1', so I can't tell if TCPRecv has lost the socket, or is just receiving empty data.

I have an old script that I was trying to finish, where I was unable to figure this issue out and simply bypassed the need to know when the socket was terminated, and I was coming back to optimize it a while later when I noticed this behavior. The correct way would be to know when the socket was terminated and react to that information, as disconnects do happen every so often, which leaves my script hung until a server reboot, essentially skipping that particular daily command.

I did search for a while, as well. But landed, mostly, on old posts without resolves beyond using a timeout, guessing the socket was dead, due to its silence.

Edited by BinaryBrother

Share this post


Link to post
Share on other sites



Hi BinaryBrother.

I ran into this issue a few weeks back, And discovered that the MSDN errorcode is not always returned to the server, If the server has never sent any information through the socket.

A working example to visualise what I mean:

Server:

OnAutoItExitRegister("kill")
TCPStartup()
Opt("TCPTimeout", 0)
$listen = TCPListen("127.0.0.1",8080)
do
    $socket = TCPaccept($listen)
until $socket <> - 1
;~ $Send = TCPsend($socket,"Ping")
ConsoleWrite("Socket created: " & $Socket & @CR)
WHILE 1
    sleep(10)
    $recv = TCPRecv($socket,1024)
    if @error = -1 then
;~      ConsoleWrite("No Data to receieve"& @CR)
    elseif @error <> 0 Then
        ConsoleWrite("Socket is closed/Unreadable. MSDN error: " & @error & @CR)
        Exit
    Else
        ConsoleWrite("Error: " & @error & @CR)
        Consolewrite("Data Receieved: " & $recv& @CR)
    EndIf
wend


func kill()
    TCPshutdown()
    Exit
EndFunc

Client:

OnAutoItExitRegister("kill")
TCPStartup()
$Server = TCPConnect("127.0.0.1",8080)
sleep(1000)
TCPSend($Server,"test data")
Sleep(1500)
TCPsend($Server,"Test Data 2")
Sleep(500)
TCPsend($Server,"Final Test")
sleep(1000)
TCPCloseSocket($server)
while 1
    sleep(50)
WEnd

func kill()
    TCPShutdown()
    Exit
EndFunc

The above will result in an endless loop, as the server never seems to receive the MSDN error code stating that the socket is closed.

Simply uncomment the TCPsend line however, and you will notice that the errorcode is then returned correctly, and the script exits...

This is probably a bug, and should probably be reported; I just haven't had the time to investigate the problem any further to build up a case proving it.

I'm assuming your server is only listening? If so, Try adding a tcpsend command in after the socket's been initialised, to see whether this helps resolve the issue.

Thanks

Javi


give a man an application, and he'll be frustrated for the day, Teach him how to program applications and he'll be frustrated for a lifetime.

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

*I think we're having different issues. However, I am often wrong. :P

My example is a Telnet Proxy, to add automation features a bit like PowerShell. Commands like "::Backup" will issue all the commands nessesary to backup the machine and trigger other variables based on output or write a custom log file.

Here are my relevant bits... ^.^
 

Global $Local_Socket, $Remote_Socket
$Local_Socket = _AcceptLocalConnection()
$Remote_Socket = _ConnectToServer()
AdlibRegister("_ReceiveData", 250)
AdlibRegister("_SendData", 250)

While 1
    Sleep(250)
WEnd

Func _AcceptLocalConnection()
    Local $Socket = -1, $MainSocket
    TCPStartup()
    $MainSocket = TCPListen("127.0.0.1", 2323)
    If $MainSocket = -1 Then Exit MsgBox(0, "ERROR", "Something is already be using port 2323!")
    TrayTip("PowerTelnet", "Connect your telnet client to '127.0.0.1' port 2323!", 20)
    While $Socket < 0
        $Socket = TCPAccept($MainSocket)
    WEnd
    TrayTip("PowerTelnet", "Accepted client connection!", 20)
    Sleep(5000)
    Return $Socket
EndFunc   ;==>_AcceptLocalConnection

Func _ConnectToServer()
    Local $Socket
    $Socket = TCPConnect("192.168.5.33", 23)
    If @error Then
        MsgBox(16, "ERROR", "Failed to Connect to server!")
    Else
        TrayTip("PowerTelnet", "Connected to server!", 20)
        Sleep(5000)
        Return $Socket
    EndIf
EndFunc   ;==>_ConnectToProxy

Func _ReceiveData()
    Local $Recv
    $Recv = TCPRecv($Remote_Socket, 2048)
    If $Recv <> "" Then
        TCPSend($Local_Socket, $Recv)
        ConsoleWrite($Recv)
    EndIf
EndFunc   ;==>_ReceiveData

Func _SendData()
    Local $Recv
    $Recv = TCPRecv($Local_Socket, 2048)
    If $Recv <> "" Then
        TCPSend($Remote_Socket, $Recv)
        ConsoleWrite($Recv)
    EndIf
EndFunc   ;==>_SendData

@error will start being triggered a few seconds after the AutoIt script has established a  connection with the server.

Edited by BinaryBrother

Share this post


Link to post
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