itljl 发表于 2010-8-24 20:05:13

Tcpconnect超时时间

TCPStartup()
$begin = TimerInit()
$Var = TCPConnect("192.5.5.5", 1000)
If @error Then
        $dif = TimerDiff($begin)
        MsgBox(0, "连接未开机的IP超时时间", $dif/1000)
EndIf
TCPShutdown()
超时时间要 20秒, 在当今网络来说,这个超时时间显然太长了,
AU3中 TCPTimeout不是用来设置这个时间的。

论坛之前有讨论过,但没有结果,只能用一个折衷的办法 先用ping检测,但这样显然不够完善,因为在WAN环境中,通过路由器很多机子是禁PING的。

所以,有没有能设置 TCPConnect 超时的办法呢?

xsjtxy 发表于 2010-8-24 20:27:28

比较另类。
if @Compiled = 0 then
msgbox(0,"","编译后再运行!")
exit
endif

if $CmdLine > 1 then
TCPStartup()
$Var = TCPConnect($CmdLine, $CmdLine)
TCPShutdown()
exit
endif


$r = run(@ScriptFullPath&" 192.5.5.5 1000")
if ProcessWaitClose($r, 5) = 0 then
ProcessClose($r)
msgbox(0,"","超时了")
endif

itljl 发表于 2010-8-24 21:28:39

回复 2# xsjtxy

呵呵,谢谢回复,这个太,,另类了,直到无法正常在程序中使用:)不管怎样还是Thanks

republican 发表于 2010-8-25 11:58:52

本帖最后由 republican 于 2010-8-25 12:29 编辑

研究了一个上午,没搞掂,还是算了ioctlsocket 的CMD值不会设置,u_long *argp这个是啥意思?Func _TCPConnect( $TCPC_IPAddr, $TCPC_IPPort )
; The following indicates that TCPStartup was already successfully called
    If Not IsDeclared( "Ws2_32_dll" ) Or ( $Ws2_32_dll = -1 ) Then
      SetError( -1 )
      Return -1
    EndIf

    Local $TCPC_m_socket, $TCPC_nRet, $TCPC_service

    $TCPC_m_socket = DLLCall( $Ws2_32_dll, "int", "socket", "int", $AF_INET, "int", $SOCK_STREAM, "int", $IPPROTO_TCP )
    If $TCPC_m_socket = $INVALID_SOCKET Then
      $TCPC_nRet = DllCall( $Ws2_32_dll, "int", "WSAGetLastError" )
      SetError( $TCPC_nRet )
      Return $SOCKET_ERROR
    EndIf

   ;--------------这里设置对的话就快了------------
;~         MsgBox(0,"Connect",$TCPC_m_socket)
        $FIONREAD = 0x4004667F
;~         $TCPC_y_socket = DLLCall( $Ws2_32_dll, "int", "ioctlsocket", "int", $TCPC_m_socket, "int", $FIONREAD, "int", 0x1 )
;~         If $TCPC_m_socket <> $INVALID_SOCKET Then
;~         $TCPC_nRet = DllCall( $Ws2_32_dll, "int", "WSAGetLastError" )
;~                 MsgBox(0,"Connect",$TCPC_nRet)
;~   EndIf
       


    $TCPC_service = DLLStructCreate( "short;USHORT;DWORD;char" )                        ;官网上这段出了问题。
    DllStructSetData( $TCPC_service, 1, $AF_INET )
   
    $TCPC_nRet = DLLCall( $Ws2_32_dll, "short", "htons", "short",$TCPC_IPPort )
    DllStructSetData( $TCPC_service, 2, $TCPC_nRet )
   
    $TCPC_nRet = DLLCall( $Ws2_32_dll, "int", "inet_addr", "str", $TCPC_IPAddr)
    DllStructSetData( $TCPC_service, 3, $TCPC_nRet )
       
    $TCPC_nRet = DLLCall( $Ws2_32_dll, "int", "connect", "int", $TCPC_m_socket, _
            "ptr", DLLStructGetPtr( $TCPC_service ), _
            "int", DllStructGetSize( $TCPC_service ) )
        $TCPC_service = 0
;~   DllStructDelete( $TCPC_service )
    If $TCPC_nRet = 0 Then
      Return $TCPC_m_socket
    Else
      $TCPC_nRet = DllCall( $Ws2_32_dll, "int", "WSAGetLastError" )
      SetError( $TCPC_nRet )
      Return $SOCKET_ERROR
    EndIf
EndFunc补充整个测试用的例子吧,需要的自己改:(官网的_TCPSEND还是有问题,也懒得改了,现在求的是连接超时,发送超时就不管了)$ip="192.168.1.104"
$port=90
#include <GUIConstants.au3>
    Global $Ws2_32_dll = -1
    Global Const $AF_INET = 2
    Global Const $SOCK_STREAM = 1
    Global Const $IPPROTO_TCP = 6
    Global Const $INVALID_SOCKET = 0
    Global Const $SOCKET_ERROR = -1
local $ret = _TCPStartup()
$startTime=TimerInit()
$ConnectedSocket = _TCPConnect($ip,$port)
If @error Then MsgBox(0,@error,$ConnectedSocket)
MsgBox(0,"",TimerDiff($startTime)/1000)
$work="Test,I M AT WORK!222"
;~ _TCPSend($ConnectedSocket,$work)
TCPSend($ConnectedSocket, $work)
Sleep(1000)
_TCPShutdown()

Func _TCPRecv( ByRef $TCPR_Socket, ByRef $TCPR_DataPtr )
; The following indicates that TCPStartup was already successfully called
    If Not IsDeclared( "Ws2_32_dll" ) Or ( $Ws2_32_dll = -1 ) Then
      SetError( -1 )
      Return -1
    EndIf

    Local $TCPR_timeout, $TCPR_bOK, $TCPR_nRet, $TCPR_Err, $readSocketSet, $z

    $TCPR_timeout = DLLStructCreate( "int;int" )
    DllStructSetData( $TCPR_timeout, 1, 0 )
    DllStructSetData( $TCPR_timeout, 2, 100 )

    $readSocketSet = DLLStructCreate( "uint;int" )
    DLLStructSetData( $readSocketSet, 1, 64 )
    For $z = 1 to 64
      DLLStructSetData( $readSocketSet, 2, $TCPR_socket, $z )
    Next
   
    $TCPR_bOK = DLLCall( $Ws2_32_dll, "int", "select", "int", 0, "ptr", DllStructGetPtr( $readSocketSet ), _
            "int_ptr", 0, "int_ptr", 0, "ptr", DllStructGetPtr( $TCPR_timeout ) )
    $TCPR_bOK = ( $TCPR_bOK > 0 )

    If $TCPR_bOK Then
      $TCPR_bOK = DLLCall( $Ws2_32_dll, "int", "__WSAFDIsSet", "int", $TCPR_socket, "ptr", DllStructGetPtr( $readSocketSet ) )
      $TCPR_bOK = Not ( $TCPR_bOK = 0 )
    EndIf
   
    If $TCPR_bOK Then
      $TCPR_nRet = DLLCall( $Ws2_32_dll, "int", "recv", "int", $TCPR_socket, _
                "ptr",DLLStructGetPtr($TCPR_DataPtr ), "int", DLLStructGetSize( $TCPR_DataPtr ), "int", 0 )
      $TCPR_nRet = $TCPR_nRet
    EndIf
   
    $TCPR_Err = DllCall( $Ws2_32_dll, "int", "WSAGetLastError" )
    SetError( $TCPR_Err )
    Return $TCPR_nRet
EndFunc

Func DllStructDelete($struct)
    $struct =0
EndFunc

Func _MAKELONG($LoWord,$HiWord)
    Return BitOR($HiWord * 0x10000, BitAND($LoWord, 0xFFFF))
EndFunc

Func _MAKEWORD($LoByte,$HiByte)
    Return BitOR($LoByte,0x100 * $HiByte)
EndFunc

Func _TCPCloseSocket( ByRef $TCPCS_Socket )
; The following indicates that TCPStartup was already successfully called
    If Not IsDeclared( "Ws2_32_dll" ) Or ( $Ws2_32_dll = -1 ) Then
      SetError( -1 )
      Return -1
    EndIf
   
    Local $TCPCS_nRet
   
    $TCPCS_nRet = DllCall( $Ws2_32_dll, "int", "closesocket", "int", $TCPCS_Socket )
    If $TCPCS_nRet = 0 Then Return 1

    $TCPCS_nRet = DllCall( $Ws2_32_dll, "int", "WSAGetLastError" )
    SetError( $TCPCS_nRet )
    Return -1
EndFunc

Func _TCPSend( ByRef $TCPS_Socket, ByRef $TCPS_DataPtr )
; The following indicates that TCPStartup was already successfully called
    If Not IsDeclared( "Ws2_32_dll" ) Or ( $Ws2_32_dll = -1 ) Then
      SetError( -1 )
      Return -1
    EndIf
    $Message=DllStructCreate("CHAR")
        if @error Then MsgBox(0,"","DllStructCreate 发生错误" & @error);

        DllStructSetData( $Message, 1, $TCPS_DataPtr )
    Local $TCPS_nRet
    MsgBox(0,"struct",DllStructGetPtr( $TCPS_DataPtr ))
    $TCPS_nRet = DllCall( $Ws2_32_dll, "int", "send", "int", $TCPS_Socket, "ptr", _
            DllStructGetPtr( $TCPS_DataPtr ), "int", DllStructGetSize( $TCPS_DataPtr ), "int", 0 )
    If $TCPS_nRet = $SOCKET_ERROR Then
      $TCPS_nRet = DllCall( $Ws2_32_dll, "int", "WSAGetLastError" )
               
      SetError( $TCPS_nRet )
      Return $SOCKET_ERROR
    EndIf
        MsgBox(0,"",$TCPS_nRet)
    Return $TCPS_nRet
EndFunc

Func _TCPConnect( $TCPC_IPAddr, $TCPC_IPPort )
; The following indicates that TCPStartup was already successfully called
    If Not IsDeclared( "Ws2_32_dll" ) Or ( $Ws2_32_dll = -1 ) Then
      SetError( -1 )
      Return -1
    EndIf

    Local $TCPC_m_socket, $TCPC_nRet, $TCPC_service

    $TCPC_m_socket = DLLCall( $Ws2_32_dll, "int", "socket", "int", $AF_INET, "int", $SOCK_STREAM, "int", $IPPROTO_TCP )
    If $TCPC_m_socket = $INVALID_SOCKET Then
      $TCPC_nRet = DllCall( $Ws2_32_dll, "int", "WSAGetLastError" )
      SetError( $TCPC_nRet )
      Return $SOCKET_ERROR
    EndIf
;~         MsgBox(0,"Connect",$TCPC_m_socket)
        $FIONREAD = 0x4004667F
;~         $TCPC_y_socket = DLLCall( $Ws2_32_dll, "int", "ioctlsocket", "int", $TCPC_m_socket, "int", $FIONREAD, "int", 0x1 )
;~         If $TCPC_m_socket <> $INVALID_SOCKET Then
;~         $TCPC_nRet = DllCall( $Ws2_32_dll, "int", "WSAGetLastError" )
;~                 MsgBox(0,"Connect",$TCPC_nRet)
;~   EndIf
       
    $TCPC_service = DLLStructCreate( "short;USHORT;DWORD;char" )                        ;官网上这段出了问题。
    DllStructSetData( $TCPC_service, 1, $AF_INET )
   
    $TCPC_nRet = DLLCall( $Ws2_32_dll, "short", "htons", "short",$TCPC_IPPort )
    DllStructSetData( $TCPC_service, 2, $TCPC_nRet )
   
    $TCPC_nRet = DLLCall( $Ws2_32_dll, "int", "inet_addr", "str", $TCPC_IPAddr)
    DllStructSetData( $TCPC_service, 3, $TCPC_nRet )
       
    $TCPC_nRet = DLLCall( $Ws2_32_dll, "int", "connect", "int", $TCPC_m_socket, _
            "ptr", DLLStructGetPtr( $TCPC_service ), _
            "int", DllStructGetSize( $TCPC_service ) )
        $TCPC_service = 0
;~   DllStructDelete( $TCPC_service )
    If $TCPC_nRet = 0 Then
      Return $TCPC_m_socket
    Else
      $TCPC_nRet = DllCall( $Ws2_32_dll, "int", "WSAGetLastError" )
      SetError( $TCPC_nRet )
      Return $SOCKET_ERROR
    EndIf
EndFunc


Func _TCPStartup( )
; Set some global variables and flags

; Initialize local variables and flags
    Local $wsaData, $nRet
    Const $WSADESCRIPTION_LEN = 256
    Const $WSASYS_STATUS_LEN = 128
   
; Structure required for WSAStartup API call
    $wsaData = DllStructCreate( "ushort;ushort;" & _
            "char[" & ( $WSADESCRIPTION_LEN + 1 ) & "];" & _
            "char[" & ( $WSASYS_STATUS_LEN + 1 ) & "];ushort;ushort;ptr")
   
; Open the Winsock DLL for subsequent API calls
    $Ws2_32_dll = DllOpen( "Ws2_32.dll" )
    If $Ws2_32_dll = -1 Then
      SetError( -2 )
      Return -1
    EndIf
   
; Actual Startup call is here "WSAStartup"
    $nRet = DLLCall( $Ws2_32_dll, "int", "WSAStartup", "short", _MAKEWORD( 2, 2 ), _
            "ptr", DLLStructGetPtr( $wsaData ) )
    SetError( $nRet )
    Return( $nRet = 0 )
EndFunc

;----------------------------------------------------------------
; _TCPShutdown( )
;
; Shutdown and cleanup TCP communications.
;
; Returns 1 for success, 0 for failure. Check @error on failure.
;----------------------------------------------------------------
Func _TCPShutdown( )
; The following indicates that TCPStartup was already successfully called
    If Not IsDeclared( "Ws2_32_dll" ) Or ( $Ws2_32_dll = -1 ) Then
      SetError( -1 )
      Return -1
    EndIf

    Local $nRet
   
; Actual shutdown call is WSACleanup API
    $nRet = DLLCall( $Ws2_32_dll, "int", "WSACleanup" )

; Close Winsock DLL
    DLLClose( $Ws2_32_dll )
    $Ws2_32_dll = -1
    SetError( $nRet )
    Return ( $nRet = 0 )
EndFunc

itljl 发表于 2010-8-25 13:52:22

回复 4# republican


    兄弟这个超时时间还是 20秒啊,改这个值在哪个位置改呢?谢谢。

republican 发表于 2010-8-25 15:01:45

都还没改好。首先ioctsocket要调用成功,然后找到fd_size的au3表示方法,才可以设置timeout.

xsjtxy 发表于 2010-8-25 17:13:22

回复 3# itljl


    我这个思路是先连接一遍。如果超时就不连接。那个5秒也可以2秒3秒。不过办法比较笨。

auto 发表于 2010-8-25 19:52:11

貌似论坛说可能会下版解决这个问题

itljl 发表于 2010-8-25 20:13:34

回复 8# auto


    链接在哪?我去观看一下!!

itljl 发表于 2010-8-25 21:27:03

据说是一个BUG?
3.3.7.0修复:http://www.autoitscript.com/trac/autoit/ticket/1573?replyto=description&reply=Reply

辣椒龙 发表于 2010-8-25 22:02:04

ping 127.0.0.1 行不行?这样应该不受防火墙什么的影响了吧

itljl 发表于 2010-8-25 22:03:45

回复 11# 辣椒龙


你ping自己不能确定别人在不在线

辣椒龙 发表于 2010-8-25 22:23:13

回复辣椒龙


你ping自己不能确定别人在不在线
itljl 发表于 2010-8-25 22:03 http://www.autoitx.com/images/common/back.gif

看来我脑袋出问题了,刚刚都不知道想到什么,把超时跟TTL联系在一起了……汗

itljl 发表于 2010-8-27 19:50:36

再顶一下,哪位仁兄能解决这个问题。
页: [1]
查看完整版本: Tcpconnect超时时间