本帖最后由 tryhi 于 2011-5-18 23:03 编辑
这里有一个很好的例子,在局域网测试通过,但用来连接外网,好像就不行了
http://www.autoitx.com/forum.php ... ght=%2B%CD%E2%CD%F8
帖子是收费贴,我把代码上传了,希望作者不要介意。
主要问题在于TCP怎么用外网连接,只需要服务端的外网IP地址就能连接么?
客户端;~ by yeqing880
TCPStartUp()
AdlibRegister ("Mem",3000)
Global $Socket
conn()
While 1
$sRecv = TCPRecv($Socket, 2048, 1)
If @error Then
AdlibUnRegister ("sendx")
conn()
EndIf
If $sRecv <> "" And $sRecv = "shutdown" Then Exit
WEnd
Func Sendx()
TCPSend ($Socket,StringToBinary("online",4))
EndFunc
Func conn()
Do
Sleep (1000)
$Socket = TCPConnect("192.168.1.71",1313)
Until $Socket <> -1
AdlibRegister ("sendx",5000)
EndFunc
Func Mem()
Local $ai_Handle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', 0x1f0fff, _
'int', False, 'int', @AutoItPID)
Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', $ai_Handle[0])
DllCall("kernel32.dll" , 'int', 'CloseHandle', 'int', $ai_Handle[0])
EndFunc
服务端;~ by yeqing880
#include "TCP.au3"
#include <date.au3>
#include <Array.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiStatusBar.au3>
#include <ListViewConstants.au3>
#include <WindowsConstants.au3>
#Include <GuiListView.au3>
Opt("GUIOnEventMode", 1)
Opt("TrayMenuMode",3)
Opt("TrayOnEventMode",1)
$displayitem = TrayCreateItem("退出")
TrayItemSetOnEvent($displayitem,"_exit")
Global $chaoshi = "",$szid = 0
Global $chaoshitime = 30 ;根据实际情况设置超时时间
Global $timeset = 1000 ;根据实际情况设置timer调用时间
Dim $lianjie[1][3]
$hServer = _TCP_Server_Create("1313","192.168.1.71")
_TCP_RegisterEvent($hServer, $TCP_NEWCLIENT, "NewClient")
_TCP_RegisterEvent($hServer, $TCP_DISCONNECT, "Disconnect")
_TCP_RegisterEvent($hServer, $TCP_RECEIVE, "rev")
$Form1 = GUICreate("Form1", 620, 562,150,100)
GUISetOnEvent($GUI_EVENT_CLOSE,"gui")
$ListView1 = GUICtrlCreateListView("Socket|IP地址", 200, 0, 419, 451)
$Menu = GUICtrlCreateContextMenu($ListView1)
$exitall= GUICtrlCreateMenuItem("全部退出",$Menu, 1)
GUICtrlSetOnEvent(-1, "shutdown2")
$Edit1 = GUICtrlCreateEdit("", 0, 0, 198, 451, BitOR($ES_AUTOVSCROLL,$ES_AUTOHSCROLL,$ES_WANTRETURN,$WS_VSCROLL))
$StatusBar1 = _GUICtrlStatusBar_Create($Form1)
Dim $StatusBar1_PartsWidth[3] = [150, 250,400]
_GUICtrlStatusBar_SetParts($StatusBar1, $StatusBar1_PartsWidth)
_GUICtrlStatusBar_SetText($StatusBar1, "服务器建立成功,监听中....", 0)
_GUICtrlStatusBar_SetText($StatusBar1, "当前在线数0", 1)
$Edit2 = GUICtrlCreateEdit("", 0, 452, 619, 89, BitOR($ES_AUTOVSCROLL,$ES_AUTOHSCROLL,$ES_WANTRETURN,$WS_VSCROLL))
GUISetState(@SW_SHOW)
$Form2 = GUICreate("数组", 411, 303, 154+620,100)
$ListView2 = GUICtrlCreateListView("ID|Socket|IP|TIME", 0, 0, 410, 302)
GUISetState(@SW_SHOW)
$Timer = DllCallbackRegister("check", "int", "hwnd;uint;uint;dword")
$TimerDLL = DllCall("user32.dll", "uint", "SetTimer", "hwnd", 0, "uint", 0, "int", $timeset, "ptr", DllCallbackGetPtr($Timer))
$Timer2 = DllCallbackRegister("check2", "int", "hwnd;uint;uint;dword")
$TimerDLL2 = DllCall("user32.dll", "uint", "SetTimer", "hwnd", 0, "uint", 0, "int", 1000, "ptr", DllCallbackGetPtr($Timer2))
While 1
Sleep (100000)
WEnd
Func NewClient($hSocket, $iError)
ReDim $lianjie[UBound($lianjie) + 1][3]
$lianjie[0][0] += 1
$lianjie[UBound($lianjie) - 1][0] = $hSocket
$lianjie[UBound($lianjie) - 1][1] = _TCP_Server_ClientIP($hSocket)
$lianjie[UBound($lianjie) - 1][2] = $chaoshitime
GUICtrlSetData ($Edit1,GUICtrlRead($edit1)&_TCP_Server_ClientIP($hSocket)&"/"&$hSocket&" 连接!"&@CRLF)
GUICtrlCreateListViewItem ($hSocket&"|"&_TCP_Server_ClientIP($hSocket),$listview1)
getonling()
EndFunc
Func rev($hSocket, $sReceived, $iError)
If $sReceived = "online" Then
$lianjie[_ArraySearch ($lianjie,$hSocket, 1, 0, 0, 0, 1)][2] = $chaoshitime
EndIf
EndFunc
Func Disconnect($hSocket, $iError)
If $hSocket = $chaoshi Then
$chaoshi = ""
Return
Else
$s = _ArraySearch ($lianjie,$hSocket, 1, 0, 0, 0, 1)
GUICtrlSetData($Edit1,GUICtrlRead($edit1)&$lianjie[$s][1]&"/"&$lianjie[$s][0]&" 离线(退出)!"&@CRLF)
_GUICtrlListView_DeleteItem ($ListView1,_GUICtrlListView_FindInText($ListView1, $lianjie[$s][0]))
_ArrayDelete($lianjie,$s)
$lianjie[0][0] -= 1
getonling()
EndIf
EndFunc
Func Shutdown2()
For $s = 1 To UBound($lianjie) - 1
TCPSend($lianjie[$s][0],"shutdown")
Next
EndFunc
Func check($hWnd, $uiMsg, $idEvent, $dwTime)
Local $s = 1
$begin = TimerInit()
While $s <= UBound($lianjie) - 1
If $lianjie[$s][2] <= 0 Then
$chaoshi = $lianjie[$s][0]
_TCP_Server_DisconnectClient($lianjie[$s][0])
GUICtrlSetData($Edit1,GUICtrlRead($edit1)&$lianjie[$s][1]&"/"&$lianjie[$s][0]&" 离线(超时)!"&@CRLF)
_GUICtrlListView_DeleteItem ($ListView1,_GUICtrlListView_FindInText($ListView1, $lianjie[$s][0]))
_ArrayDelete($lianjie,$s)
$lianjie[0][0] -= 1
getonling()
GUICtrlSetData($Edit2,"超时检测完成,耗时大约"&Round (TimerDiff($begin),2)&"秒 当前时间:"&_Now()&@CRLF&GUICtrlRead($Edit2))
Return
Else
If $lianjie[$s][0] <> "del" Then $lianjie[$s][2] -= 1
EndIf
$s += 1
WEnd
GUICtrlSetData($Edit2,"超时检测完成,耗时大约"&Round (TimerDiff($begin),2)&"秒 当前时间:"&_Now()&@CRLF&GUICtrlRead($Edit2))
EndFunc
Func check2($hWnd, $uiMsg, $idEvent, $dwTime)
GUICtrlSendMsg($ListView2, $LVM_DELETEALLITEMS, 0, 0)
GUICtrlCreateListViewItem ("0||||",$ListView2)
For $s = 1 To UBound($lianjie) - 1
GUICtrlCreateListViewItem($s&"|"&$lianjie[$s][0]&"|"&$lianjie[$s][1]&"|"&$lianjie[$s][2],$ListView2)
Next
EndFunc
Func getonling()
_GUICtrlStatusBar_SetText($StatusBar1, "当前在线数"&UBound($lianjie)-1, 1)
EndFunc
Func gui()
Switch @GUI_CtrlId
Case $GUI_EVENT_CLOSE
_exit()
EndSwitch
EndFunc
Func _exit()
DllCallbackFree($Timer)
Sleep (1000)
_TCP_Server_Stop()
Exit
EndFunc
需要用到这个UDF
续:回复都很精辟,不知选哪条 |