Jump to content

TCPConnect( $sIPAddr , $iPort [, $iTimeOut ] )


JScript
 Share

Recommended Posts

Hello everybody,

Many people have complained that the function Opt("TCPTimeout", ...) not working in TCPConnect(), so I decided to try bypass the problem as the solution: TCPConnect Timeout (Milestone: Future Release) still not available!

My thanks to @trancexx for the excellent work with Mailslots...

Easy to adapt to your code; use these functions instead of native:

; #CURRENT# =====================================================================================================================
; _TCPStartup
; _TCPShutdown
; _TCPListen
; _TCPConnect
; _TCPCloseSocket
; ===============================================================================================================================

Here's a link to the source code and examples:

TCP_TimeOut.zip

Use this code instead:

; #FUNCTION# ====================================================================================================================
; Name...........: _TCPConnect
; Description ...: Triess to establishes a TCP-connection in a specified time limit
; Syntax.........: _TCPConnect($sIPAddr, $iPort, $iTimeOut = -1)
; Parameters ....: $sIpAddr - IP address to connect to (IPv4)
; $iPort - Port to use
; $iTimeOut - Timeout for connection in milliseconds (default: -1)
; |Values < 0: default timeout
; |Values 0, Keyword Default: use time from Opt("TCPTimeout")
; |Values > 0: timeout in milliseconds
; Return values .: Success - Socket to use with TCP-functions
; Failure - -1, sets @error
; |1 - $sIpAddr incorrect
; |2 - could not get port
; |3 - could not create socket
; |4 - could not connect
; |5 - could not get WSAError
; |and errors from WSAGetLastError
; Author ........: ProgAndy
; Modified.......: JScript
; Remarks .......:
; Related .......: TCPConnect, TCPCloseSocket, TCPSend, TCPRecv
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func _TCPConnect($sIPAddr, $iPort, $iTimeOut = -1)
Local $hWs2 = DllOpen("Ws2_32.dll")
Local $iDllErr, $fError = False, $aRes
Local $hSock = DllCall($hWs2, "uint", "socket", "int", 2, "int", 1, "int", 6)
If @error Then
$iDllErr = 3
ElseIf $hSock[0] = 4294967295 Or $hSock[0] = -1 Then
$fError = True
Else
$hSock = $hSock[0]
$aRes = DllCall($hWs2, "ulong", "inet_addr", "str", $sIPAddr)
If @error Or $aRes[0] = -1 Or $aRes[0] = 4294967295 Then
$iDllErr = 1
Else
$iPort = DllCall($hWs2, "ushort", "htons", "ushort", $iPort)
If @error Then
$iDllErr = 2
Else
$iPort = $iPort[0]
EndIf
EndIf
If 0 = $iDllErr Then
Local $tSockAddr = DllStructCreate("short sin_family;ushort sin_port; ulong sin_addr;char sin_zero[8];")
DllStructSetData($tSockAddr, 1, 2)
DllStructSetData($tSockAddr, 2, $iPort)
DllStructSetData($tSockAddr, 3, $aRes[0])

If IsKeyword($iTimeOut) Or $iTimeOut = 0 Then $iTimeOut = Opt("TCPTimeout")

If $iTimeOut > -1 Then DllCall($hWs2, "int", "ioctlsocket", "int", $hSock, "long", 0x8004667e, "uint*", 1)
$aRes = DllCall($hWs2, "int", "connect", "int", $hSock, "ptr", DllStructGetPtr($tSockAddr), "int", DllStructGetSize($tSockAddr))

Select
Case @error
$iDllErr = 4
Case $aRes[0] <> 0
$aRes = DllCall($hWs2, "int", "WSAGetLastError")
If Not @error And $aRes[0] = 10035 Then ContinueCase
$fError = True
Case $iTimeOut > -1
If IsKeyword($iTimeOut) Or $iTimeOut = 0 Then $iTimeOut = Opt("TCPTimeout")
Local $t = DllStructCreate("uint;int")
DllStructSetData($t, 1, 1)
DllStructSetData($t, 2, $hSock)
Local $to = DllStructCreate("long;long")
DllStructSetData($to, 1, Floor($iTimeOut / 1000))
DllStructSetData($to, 2, Mod($iTimeOut, 1000))
$aRes = DllCall($hWs2, "int", "select", "int", $hSock, "ptr", DllStructGetPtr($t), "ptr", DllStructGetPtr($t), "ptr", 0, "ptr", DllStructGetPtr($to))
If Not @error And $aRes[0] = 0 Then
$aRes = DllCall($hWs2, "int", "WSAGetLastError")
If Not @error And $aRes[0] = 0 Then
$iDllErr = 10060
Else
$fError = True
EndIf
Else
DllCall($hWs2, "int", "ioctlsocket", "int", $hSock, "long", 0x8004667e, "uint*", 0)
EndIf
EndSelect
EndIf
EndIf
If $iDllErr Then
TCPCloseSocket($hSock)
$hSock = -1
ElseIf $fError Then
$iDllErr = DllCall($hWs2, "int", "WSAGetLastError")
If Not @error Then $iDllErr = $iDllErr[0]
If $iDllErr = 0 Then $iDllErr = 5
TCPCloseSocket($hSock)
$hSock = -1
EndIf
DllClose($hWs2)
Return SetError($iDllErr, 0, $hSock)
EndFunc ;==>_TCPConnect

It was tested in virtual machines and also in a real network with 38 computers.

I wait for comments / criticisms / suggestions...

Edit: The only solution I found for the problem of TCPConnect()

Edit2: Project that I was'm using this UDF:

Posted Image

Edited by JScript

http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)

Somewhere Out ThereJames Ingram

somewh10.png

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!

Link to comment
Share on other sites

Well, your description sucks :unsure: But having looked through the code to figure it out myself... nice job.

I'd still like a better description of the problem you're actually trying to solve though. How does this differ from using Opt("TCPTimeout", ...)?

Link to comment
Share on other sites

Well, your description sucks :unsure: But having looked through the code to figure it out myself... nice job.

I'd still like a better description of the problem you're actually trying to solve though. How does this differ from using Opt("TCPTimeout", ...)?

Ok, I'll change the description.

"How does this differ from using Opt(" TCPtimeout "...)?" Is that this option does not work for TCPConnect()...

http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)

Somewhere Out ThereJames Ingram

somewh10.png

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!

Link to comment
Share on other sites

Ah, gotcha. Too bad it only works with another autoit script on the other end of the connection, but it's still a nice solution.

Well, that's true...

But I'm trying another way, so I have fun while have not reached the definitive solution!

http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)

Somewhere Out ThereJames Ingram

somewh10.png

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!

Link to comment
Share on other sites

I'm trying to use this little program: http://support.microsoft.com/?id=832919 together with the UDF: - by @trancexx

page__view__findpost__p__883657, but still no reply...

This code below works without any limitation, but the console window pops up - already got hide but I do not read the return...

http://www.mediafire.com/?gsx0wx71ul7fi07

http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)

Somewhere Out ThereJames Ingram

somewh10.png

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!

Link to comment
Share on other sites

  • 2 weeks later...

Hm, on my virtual PC and real pc, i`m alwayse get error code 4, when i`m run script examples (Server first, then client).

When i`m try to use _TCP_TimeOut.au3 in my test scripts - i`m alwayse get -1(socket Unavailable). Im disable all firewalls and etc.

Do you know any soltion on this problem ?

PS:defaulst TPCconnect - works fine, but non work TCPtimeout.

Link to comment
Share on other sites

Hm, on my virtual PC and real pc, i`m alwayse get error code 4, when i`m run script examples (Server first, then client).

When i`m try to use _TCP_TimeOut.au3 in my test scripts - i`m alwayse get -1(socket Unavailable). Im disable all firewalls and etc.

Do you know any soltion on this problem ?

PS:defaulst TPCconnect - works fine, but non work TCPtimeout.

@error code 4 = TimeOut...

Which TimeOut value did you use?

Note: In example (Server.au3/Client.au3) are the IPs with the same address

Local $szIPADDRESS = @IPAddress1

just leave it on the server and client point the address of the server...

Reply me if it worked...

http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)

Somewhere Out ThereJames Ingram

somewh10.png

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!

Link to comment
Share on other sites

I find problem. Pc where i test script - in domain, and script return name 'pcname.xxx.xxx.local' that`s a problem. When i`m add in function _TCPConnect

this string - '$sHostName=StringLeft($sHostName,StringInStr($sHostName,'.')-1)' the examples works fine!

Link to comment
Share on other sites

Good idea, but there is a better way to do that if you use the winsock-functions directly in _TCPConnect. Then you only need a modified TCPConnect and the server can be anything.

(just pseudocode)

_TCPConnect($ip, $port, $timeout)

- create socket (func: socket)

- set nonblocking (func: setsockopt)

- connect (func: connect)

- wait for connectoin with timeout: (func: select)

- if timeout: closesocket / TCPCloseSocket?

- else: set blocking back (func: setsockopt)

- return

Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

@root991

Ok, thanks.

@ProgAndy

Yes! I had seen this possibility, but I do not know much about programming (I do not know how to pass the MSDN examples for AutoIt)

If you can post a code for this, it would be great!

http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)

Somewhere Out ThereJames Ingram

somewh10.png

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!

Link to comment
Share on other sites

@ProgAndy

Yes! I had seen this possibility, but I do not know much about programming (I do not know how to pass the MSDN examples for AutoIt)

If you can post a code for this, it would be great!

Here it is. I did too much error checking...
; #FUNCTION# ====================================================================================================================
; Name...........: _TCPConnect
; Description ...: Triess to establishes a TCP-connection in a specified time limit
; Syntax.........: _ArrayAdd(ByRef $avArray, $vValue)
; Parameters ....: $sIpAddr  - IP address to connect to (IPv4)
;                  $iPort    - Port to use
;                  $iTimeOut - Timeout for connection in milliseconds (default: -1)
;                  |Values < 0: default timeout
;                  |Values 0, Keyword Default: use time from Opt("TCPTimeout")
;                  |Values > 0: timeout in milliseconds
; Return values .: Success - Socket to use with TCP-functions
;                  Failure - -1, sets @error
;                  |1 - $sIpAddr incorrect
;                  |2 - could not get port
;                  |3 - could not create socket
;                  |4 - could not connect
;                  |5 - could not get WSAError
;                  |and errors from WSAGetLastError
; Author ........: ProgAndy
; Modified.......:
; Remarks .......:
; Related .......: TCPConnect, TCPCloseSocket, TCPSend, TCPRecv
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func _TCPConnect($sIpAddr, $iPort, $iTimeOut = -1)
    Local $hWs2 = DllOpen("Ws2_32.dll")
    Local $iDllErr, $fError=False, $aRes
    Local $hSock = DllCall($hWs2, "uint", "socket", "int", 2, "int", 1, "int", 6)
    If @error Then
        $iDllErr = 3
    ElseIf $hSock[0] = 4294967295 Or $hSock[0] = -1 Then
        $fError = True
    Else
        $hSock = $hSock[0]
        $aRes = DllCall($hWs2, "ulong", "inet_addr", "str", $sIpAddr)
        If @error Or $aRes[0] = -1 Or $aRes[0] = 4294967295 Then
            $iDllErr = 1
        Else
            $iPort = DllCall($hWs2, "ushort", "htons", "ushort", $iPort)
            If @error Then
                $iDllErr = 2
            Else
                $iPort = $iPort[0]
            EndIf
        EndIf
        If 0 = $iDllErr Then
            Local $tSockAddr = DllStructCreate("short sin_family;ushort sin_port; ulong sin_addr;char sin_zero[8];")
            DllStructSetData($tSockAddr, 1, 2)
            DllStructSetData($tSockAddr, 2, $iPort)
            DllStructSetData($tSockAddr, 3, $aRes[0])
            If $iTimeOut > -1 Then DllCall($hWs2, "int", "ioctlsocket", "int", $hSock, "long", 0x8004667e, "uint*", 1)
            $aRes = DllCall($hWs2, "int", "connect", "int", $hSock, "ptr", DllStructGetPtr($tSockAddr), "int", DllStructGetSize($tSockAddr))
            Select
                Case @error
                    $iDllErr = 4
                Case $aRes[0] <> 0
                    $aRes = DllCall($hWs2, "int", "WSAGetLastError")
                    If Not @error And $aRes[0] = 10035 Then ContinueCase
                    $fError = True
                Case $iTimeOut > -1
                    If IsKeyword($iTimeOut) Or $iTimeOut = 0 Then $iTimeOut = Opt("TCPTimeout")
                    Local $t = DllStructCreate("uint;int")
                    DllStructSetData($t, 1, 1)
                    DllStructSetData($t, 2, $hSock)
                    Local $to = DllStructCreate("long;long")
                    DllStructSetData($to, 1, Floor($iTimeOut/1000))
                    DllStructSetData($to, 2, Mod($iTimeOut, 1000))
                    $aRes = DllCall($hWs2, "int", "select", "int", $hSock, "ptr", DllStructGetPtr($t), "ptr", DllStructGetPtr($t), "ptr", 0, "ptr", DllStructGetPtr($to))
                    If Not @error And $aRes[0] = 0 Then
                        $aRes = DllCall($hWs2, "int", "WSAGetLastError")
                        If Not @error And $aRes[0] = 0 Then
                            $iDll = 10060
                        Else
                            $fError = True
                        EndIf
                    Else
                        DllCall($hWs2, "int", "ioctlsocket", "int", $hSock, "long", 0x8004667e, "uint*", 0)
                    EndIf
            EndSelect
        EndIf
    EndIf
    If $iDllErr Then
        TCPCloseSocket($hSock)
        $hSock = -1
    ElseIf $fError Then
        $iDllErr = DllCall($hWs2, "int", "WSAGetLastError")
        If Not @error Then $iDllErr = $iDllErr[0]
        If $iDllErr = 0 Then $iDllErr = 5
        TCPCloseSocket($hSock)
        $hSock = -1
    EndIf
    DllClose($hWs2)
    Return SetError($iDllErr, 0, $hSock)
EndFunc

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

@ProgAndy: Wonderful! :>

But:

Variable used without being declared:

$iDll = 10060
I change to this:
$iDllErr = 10060

Default keyword not work:

Case $iTimeOut > -1
    If IsKeyword($iTimeOut) Or $iTimeOut = 0 Then $iTimeOut = Opt("TCPTimeout")
I change to this:
If IsKeyword($iTimeOut) Or $iTimeOut = 0 Then $iTimeOut = Opt("TCPTimeout")
If $iTimeOut > -1 Then DllCall($hWs2, "int", "ioctlsocket", "int", $hSock, "long", 0x8004667e, "uint*", 1)

Modified code:

; #FUNCTION# ====================================================================================================================
; Name...........: _TCPConnect
; Description ...: Triess to establishes a TCP-connection in a specified time limit
; Syntax.........: _TCPConnect($sIPAddr, $iPort, $iTimeOut = -1)
; Parameters ....: $sIpAddr  - IP address to connect to (IPv4)
;                  $iPort    - Port to use
;                  $iTimeOut - Timeout for connection in milliseconds (default: -1)
;                  |Values < 0: default timeout
;                  |Values 0, Keyword Default: use time from Opt("TCPTimeout")
;                  |Values > 0: timeout in milliseconds
; Return values .: Success - Socket to use with TCP-functions
;                  Failure - -1, sets @error
;                  |1 - $sIpAddr incorrect
;                  |2 - could not get port
;                  |3 - could not create socket
;                  |4 - could not connect
;                  |5 - could not get WSAError
;                  |and errors from WSAGetLastError
; Author ........: ProgAndy
; Modified.......:
; Remarks .......:
; Related .......: TCPConnect, TCPCloseSocket, TCPSend, TCPRecv
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func _TCPConnect($sIPAddr, $iPort, $iTimeOut = -1)
    Local $hWs2 = DllOpen("Ws2_32.dll")
    Local $iDllErr, $fError = False, $aRes
    Local $hSock = DllCall($hWs2, "uint", "socket", "int", 2, "int", 1, "int", 6)
    If @error Then
        $iDllErr = 3
    ElseIf $hSock[0] = 4294967295 Or $hSock[0] = -1 Then
        $fError = True
    Else
        $hSock = $hSock[0]
        $aRes = DllCall($hWs2, "ulong", "inet_addr", "str", $sIPAddr)
        If @error Or $aRes[0] = -1 Or $aRes[0] = 4294967295 Then
            $iDllErr = 1
        Else
            $iPort = DllCall($hWs2, "ushort", "htons", "ushort", $iPort)
            If @error Then
                $iDllErr = 2
            Else
                $iPort = $iPort[0]
            EndIf
        EndIf
        If 0 = $iDllErr Then
            Local $tSockAddr = DllStructCreate("short sin_family;ushort sin_port; ulong sin_addr;char sin_zero[8];")
            DllStructSetData($tSockAddr, 1, 2)
            DllStructSetData($tSockAddr, 2, $iPort)
            DllStructSetData($tSockAddr, 3, $aRes[0])

            If IsKeyword($iTimeOut) Or $iTimeOut = 0 Then $iTimeOut = Opt("TCPTimeout")

            If $iTimeOut > -1 Then DllCall($hWs2, "int", "ioctlsocket", "int", $hSock, "long", 0x8004667e, "uint*", 1)
            $aRes = DllCall($hWs2, "int", "connect", "int", $hSock, "ptr", DllStructGetPtr($tSockAddr), "int", DllStructGetSize($tSockAddr))

            Select
                Case @error
                    $iDllErr = 4
                Case $aRes[0] <> 0
                    $aRes = DllCall($hWs2, "int", "WSAGetLastError")
                    If Not @error And $aRes[0] = 10035 Then ContinueCase
                    $fError = True
                Case $iTimeOut > -1
                    If IsKeyword($iTimeOut) Or $iTimeOut = 0 Then $iTimeOut = Opt("TCPTimeout")
                    Local $t = DllStructCreate("uint;int")
                    DllStructSetData($t, 1, 1)
                    DllStructSetData($t, 2, $hSock)
                    Local $to = DllStructCreate("long;long")
                    DllStructSetData($to, 1, Floor($iTimeOut / 1000))
                    DllStructSetData($to, 2, Mod($iTimeOut, 1000))
                    $aRes = DllCall($hWs2, "int", "select", "int", $hSock, "ptr", DllStructGetPtr($t), "ptr", DllStructGetPtr($t), "ptr", 0, "ptr", DllStructGetPtr($to))
                    If Not @error And $aRes[0] = 0 Then
                        $aRes = DllCall($hWs2, "int", "WSAGetLastError")
                        If Not @error And $aRes[0] = 0 Then
                            $iDllErr = 10060
                        Else
                            $fError = True
                        EndIf
                    Else
                        DllCall($hWs2, "int", "ioctlsocket", "int", $hSock, "long", 0x8004667e, "uint*", 0)
                    EndIf
            EndSelect
        EndIf
    EndIf
    If $iDllErr Then
        TCPCloseSocket($hSock)
        $hSock = -1
    ElseIf $fError Then
        $iDllErr = DllCall($hWs2, "int", "WSAGetLastError")
        If Not @error Then $iDllErr = $iDllErr[0]
        If $iDllErr = 0 Then $iDllErr = 5
        TCPCloseSocket($hSock)
        $hSock = -1
    EndIf
    DllClose($hWs2)
    Return SetError($iDllErr, 0, $hSock)
EndFunc   ;==>_TCPConnect

After a few tests I'll remove my code and leave only your! :unsure:

Edited by jscript

http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!)

Somewhere Out ThereJames Ingram

somewh10.png

dropbo10.pngDownload Dropbox - Simplify your life!
Your virtual HD wherever you go, anywhere!

Link to comment
Share on other sites

Variable used without being declared:

Once I rely on the autocompletion of SciTE and then I forget to press enter...

PS: You forgot to remove the If after "Case -1". It's no error, ut it is unnecessary and redundant since you moved it to the top.

Edit: I wrote Triess in the description :unsure:

Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

@ProgAndy

$iTimeOut: It appears the minimum safe value is 500...

That depends on your internet connection. For localhost even 10ms are enough :unsure:

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

  • 1 year later...

A big thank to ProgAndy for his code and JScript for the modified version. Just what I was after

Edited by rogdog
My Scripts[topic="73325"]_ReverseDNS()[/topic]Favourite scripts by other members[topic="81687"]SNMP udf[/topic][topic="70759"]Using SNMP - MIB protocol[/topic][topic="39050"]_SplitMon:Section off your monitor!, split your monitor into sections for easy management[/topic][topic="73425"]ZIP.au3 UDF in pure AutoIt[/topic][topic="10534"]WMI ScriptOMatic tool for AutoIt[/topic][topic="51103"]Resources UDF embed/use any data/files into/from AutoIt compiled EXE files[/topic]
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...