Jump to content

Recommended Posts

Posted (edited)

Honestly, the solution was to use different method instead of TCP IP to send data between machines, albeit NOT elegant but I less hassle.

But with respect to my original query, I still have problems detecting TCP-IP disconnection using TCPRecv. I was very frustrated so I simply switched method.
If anyone cares to debug:

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

AutoIt Version: 3.3.8.1 (Or greater)
Author:      Ken Piper

Script Function:
    Template multi-client server base code.
    Use as a base for making an efficient server program.

    This base will just accept connections and echo back what it receives,
        and kill the connection if it is dead or inactive for x seconds.
    It will not do any other work, that must be added seperately!

#ce ----------------------------------------------------------------------------

#include <Array.au3>
TCPStartup()
Opt("TCPTimeout", 0)

#region ;Safe-to-edit things are below
Global $BindIP = "0.0.0.0"  ;Listen on all addresses
Global $BindPort = 8080     ;Listen on port 8080
Global $PacketSize = 512    ;Max packet size per-check
Global $MaxClients = 10     ;Max simultaneous clients
#endregion ;Stuff you shouldn't touch is below

Global $Listen
Global $Clients[1][4] = [[0,0,0,0]] ;[Index][Socket, IP, Timestamp, Buffer]
Global $Ws2_32 = DllOpen("Ws2_32.dll") ;Open Ws2_32.dll, it might get used a lot
Global $NTDLL = DllOpen("ntdll.dll") ;Open ntdll.dll, it WILL get used a lot

OnAutoItExitRegister("ExitProcedure") ;Register this function to be called if the server needs to exit

$Listen = TCPListen($BindIP, $BindPort, $MaxClients) ;Start listening on the given IP/port
If @error Then Exit 1 ;Exit with return code 1 if something was already bound to that IP and port

while 1
    local $i
    local $iSock = TCPAccept($Listen)   ;See if anything wants to connect
    if $iSock <> -1 then
        $busy = 1
        $i = UBound($Clients, 1)    ;get the number of current connections
        if $i >= $MaxClients then   ;maxclients reached
            TCPCloseSocket($iSock)  ;drop the new connection
        else
            _ArrayAdd($Clients, "0|0|0|0")          ;allocate space for new connection
            $Clients[$i][0] = $iSock            ;Set the socket ID of the connection
            $Clients[$i][2] = TimerInit()           ;Set the timestamp for the last known activity timer
            $Clients[$i][3] = ""                ;Blank the recv buffer
            TCPSend($Clients[$i][0], "Welcome Client #"&$i&@CRLF)
        endif
    endif

    ;This part Checks buffers and do things starting at 1st connection
    $i = 1  
    while $i < UBound($Clients,1)   ;loop through all clients starting at 1st position
        local $sRecv = TCPRecv($Clients[$i][0], $PacketSize) ;read from client's connection
        if $sRecv = "" AND @error < 0 then  ;connection error
            TCPCloseSocket($Clients[$i][0]) ;close the connection
            _ArrayDelete($Clients, $i)  ;delete allocation
        else
            $Clients[$i][2] = TimerInit()   ;update the activity timer
            $Clients[$i][3] &= $sRecv   ;add data to buffer
            if StringInStr($Clients[$i][3], @CRLF, 0) then
                TCPSend($Clients[$i][0], "Echoing line: " & $Clients[$i][3]) ;Echo back the packet the client sent
                if StringInStr($Clients[$i][3],"?",0) then
                    TCPSend($Clients[$i][0], "UBound($Clients,1): " & UBound($Clients,1) & @CRLF) 
                endif
                $Clients[$i][3] = ''
            endif
            $i += 1
        endif
    wend

    sleep(10)
wEnd

Func ExitProcedure()
    DllClose($Ws2_32) ;Close the open handle to Ws2_32.dll
    DllClose($NTDLL) ;Close the open handle to ntdll.dll
    For $i = 1 To $Clients[0][0] ;Loop through the connected clients
        TCPCloseSocket($Clients[$i][0]) ;Force the client's connection closed
    Next
    TCPShutdown() ;Shut down networking stuff
EndFunc

TCPRecv is not giving me the @error I was hoping for. I tried @error > 0, @error < 0 and @error <> 0,  nothing worked.

 

 

 

Original script uses a timer to disconnect idle users. I dont want timer to disconnect users.

 

 

Edited by jsteng

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
  • Recently Browsing   0 members

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