找回密码
 加入
搜索
查看: 6796|回复: 13

[网络通信] Tcpconnect超时时间

  [复制链接]
发表于 2010-8-24 20:05:13 | 显示全部楼层 |阅读模式
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 超时的办法呢?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2010-8-24 20:27:28 | 显示全部楼层
比较另类。
if @Compiled = 0 then
msgbox(0,"","编译后再运行!")
exit
endif

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


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

评分

参与人数 1金钱 +20 收起 理由
afan + 20

查看全部评分

 楼主| 发表于 2010-8-24 21:28:39 | 显示全部楼层
回复 2# xsjtxy

呵呵,谢谢回复,这个太,,另类了,直到无法正常在程序中使用:)不管怎样还是Thanks
发表于 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[0] = $INVALID_SOCKET Then
        $TCPC_nRet = DllCall( $Ws2_32_dll, "int", "WSAGetLastError" )
        SetError( $TCPC_nRet[0] )
        Return $SOCKET_ERROR
    EndIf

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


    $TCPC_service = DLLStructCreate( "short;USHORT;DWORD;char[8]" )                        ;官网上这段出了问题。
    DllStructSetData( $TCPC_service, 1, $AF_INET )
    
    $TCPC_nRet = DLLCall( $Ws2_32_dll, "short", "htons", "short",$TCPC_IPPort )
    DllStructSetData( $TCPC_service, 2, $TCPC_nRet[0] )
   
    $TCPC_nRet = DLLCall( $Ws2_32_dll, "int", "inet_addr", "str", $TCPC_IPAddr)
    DllStructSetData( $TCPC_service, 3, $TCPC_nRet[0] )
         
    $TCPC_nRet = DLLCall( $Ws2_32_dll, "int", "connect", "int", $TCPC_m_socket[0], _
            "ptr", DLLStructGetPtr( $TCPC_service ), _
            "int", DllStructGetSize( $TCPC_service ) )
        $TCPC_service = 0
;~     DllStructDelete( $TCPC_service )
    If $TCPC_nRet[0] = 0 Then
        Return $TCPC_m_socket[0]
    Else
        $TCPC_nRet = DllCall( $Ws2_32_dll, "int", "WSAGetLastError" )
        SetError( $TCPC_nRet[0] )
        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[64]" )
    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] > 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] = 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[0]
    EndIf
    
    $TCPR_Err = DllCall( $Ws2_32_dll, "int", "WSAGetLastError" )
    SetError( $TCPR_Err[0] )
    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] = 0 Then Return 1

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

评分

参与人数 1金钱 +30 收起 理由
afan + 30

查看全部评分

 楼主| 发表于 2010-8-25 13:52:22 | 显示全部楼层
回复 4# republican


    兄弟这个超时时间还是 20秒啊,改这个值在哪个位置改呢?谢谢。
发表于 2010-8-25 15:01:45 | 显示全部楼层
都还没改好。首先ioctsocket要调用成功,然后找到fd_size的au3表示方法,才可以设置timeout.
发表于 2010-8-25 17:13:22 | 显示全部楼层
回复 3# itljl


    我这个思路是先连接一遍。如果超时就不连接。那个5秒也可以2秒3秒。不过办法比较笨。
发表于 2010-8-25 19:52:11 | 显示全部楼层
貌似论坛说可能会下版解决这个问题
 楼主| 发表于 2010-8-25 20:13:34 | 显示全部楼层
回复 8# auto


    链接在哪?我去观看一下!!
 楼主| 发表于 2010-8-25 21:27:03 | 显示全部楼层
据说是一个BUG?
3.3.7.0修复:http://www.autoitscript.com/trac ... ion&reply=Reply
发表于 2010-8-25 22:02:04 | 显示全部楼层
ping 127.0.0.1 行不行?这样应该不受防火墙什么的影响了吧
 楼主| 发表于 2010-8-25 22:03:45 | 显示全部楼层
回复 11# 辣椒龙


你ping自己不能确定别人在不在线
发表于 2010-8-25 22:23:13 | 显示全部楼层
回复  辣椒龙


你ping自己不能确定别人在不在线
itljl 发表于 2010-8-25 22:03


看来我脑袋出问题了,刚刚都不知道想到什么,把超时跟TTL联系在一起了……汗
 楼主| 发表于 2010-8-27 19:50:36 | 显示全部楼层
再顶一下,哪位仁兄能解决这个问题。
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-5-22 16:21 , Processed in 0.096362 second(s), 29 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表