|
本帖最后由 夜猫猫 于 2012-9-23 14:45 编辑
原码是网管联盟ThinKing的列子
服务端#Region ;**** 参数创建于 ACNWrapper_GUI ****
#AutoIt3Wrapper_icon=include\Ser.ico
#EndRegion ;**** 参数创建于 ACNWrapper_GUI ****
#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <WindowsConstants.au3>
#include <array.au3>
#include <EditConstants.au3>
;~ #include <ListViewConstants.au3>
#include <GuiListView.au3>
Opt("GUIOnEventMode", 1) ;GUIi事件模式
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("服务端", 456, 309 + 150 + 30, 315, 196)
;GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") ;去掉此调用客户端能正常接收
GUISetOnEvent($GUI_EVENT_CLOSE, "_gui")
$ListView1 = GUICtrlCreateListView("socket|IP", 8, 8, 442, 286, 0x0008)
$Edit1 = GUICtrlCreateEdit("", 8, 300, 220, 150, BitOR($ES_WANTRETURN, $WS_VSCROLL))
$Edit2 = GUICtrlCreateEdit("", 8 + 220, 300, 220, 150, BitOR($ES_WANTRETURN, $WS_VSCROLL))
$listmenu1 = GUICtrlCreateContextMenu($ListView1);给一个控件建上下文菜单(右键菜单)
$menu1 = GUICtrlCreateMenuItem("发送", $listmenu1)
GUICtrlSetOnEvent(-1, "_gui")
$button1 = GUICtrlCreateButton("array", 8, 309 + 150 + 30 - 30)
GUICtrlSetOnEvent(-1, "_gui")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
Global $szIPADDRESS = @IPAddress1 ;你的公共IP地址
Global $nPORT = 33892;端口
Global $MainSocket, $GOOEY, $edit, $ConnectedSocket, $szIP_Accepted
Global $msg, $recv
Global $OnlineList[1][2] ;在线列表
; 开始 TCP 服务
;==============================================
TCPStartup()
$ConnectedSocket = -1
$MainSocket = TCPListen($szIPADDRESS, $nPORT)
If $MainSocket = -1 Then
MsgBox(64,"提示","创建监听失败,程序无法运行,请重新设置端口")
Exit
EndIf
AdlibRegister("_ReduceMemory", 1000 * 10) ;10秒整理一次内存
AdlibRegister("_AcceptAndDelList") ;默认250MS检测一次是否有新客户机连接与删除旧客户机
_ReduceMemory()
While 1
Sleep(1000)
WEnd
Func _Gui()
Switch @GUI_CtrlId
Case $GUI_EVENT_CLOSE
Exit
Case $button1
_ArrayDisplay($OnlineList)
Case $menu1
$Tinput = InputBox("请输入数据", "")
If Not @error Then
_SendText($Tinput)
EndIf
EndSwitch
EndFunc ;==>_Gui
Func _SendText($Text);将数据转换成二进制再发送
$totalnum = _GUICtrlListView_GetItemCount($ListView1)
$selectcount = _GUICtrlListView_GetSelectedCount($ListView1)
$out = ""
For $i = 0 To $totalnum - 1
If $selectcount Then
If _GUICtrlListView_GetItemSelected($ListView1, $i) == True Then
$Lsocket = _GUICtrlListView_GetItemText($ListView1, $i, 0)
TCPSend($Lsocket, StringToBinary("Control_Msg|" & $Text, 4))
;~ TCPSend($Lsocket, StringToBinary("Control_Msg|" & $Text, 4))
;~ MsgBox(0,0,$Lsocket)
EndIf
Else
;~ $out = "没有选择文件"
EndIf
Next
EndFunc ;==>_SendText
Func _AcceptAndDelList();定时接受与删除列表
$begin = TimerInit()
AdlibUnRegister("_AcceptAndDelList")
_Accept();接受新客户机
_Recv_Dellist();删除离线的客户机
AdlibRegister("_AcceptAndDelList")
GUICtrlSetData($Edit1, Round(TimerDiff($begin), 3) & " MS" & @CRLF, "|")
EndFunc ;==>_AcceptAndDelList
Func _Accept() ;接受新客户端连接,并维护socket表
$ConnectedSocket = TCPAccept($MainSocket)
If $ConnectedSocket <> -1 Then ;<>-1表示有新客户端连接
$szIP_Accepted = SocketToIP($ConnectedSocket) ;socket转成
$all = UBound($OnlineList) + 1
ReDim $OnlineList[$all][2] ;在线列表数组增加
$OnlineList[$all - 1][0] = $ConnectedSocket ;socket
$OnlineList[$all - 1][1] = $szIP_Accepted ;ip
WinSetTitle($Form1, "", "服务端,共在线:" & UBound($OnlineList) - 1 & " 台机子")
GUICtrlCreateListViewItem($OnlineList[$all - 1][0] & "|" & $OnlineList[$all - 1][1], $ListView1)
GUICtrlSetData($Edit2, $szIP_Accepted & " 上线 - " & @HOUR & ":" & @MIN & ":" & @SEC & @CRLF, "|")
EndIf
EndFunc ;==>_Accept
Func _Recv_Dellist() ;接收客户机发来数据并删除关闭的socket列表
For $i = 1 To UBound($OnlineList) - 1
;~ $recv = TCPsend($OnlineList[$i][0], "") ;废时间
$recv = TCPSend($OnlineList[$i][0], 10)
If @error Then
;搜索LISTVIEW中需要离线的,并删除
$a = ControlListView($Form1, "", $ListView1, "FindItem", $OnlineList[$i][0]) ;获取GUI上的socket的listview的行
$Del_ip = _GUICtrlListView_GetItemText($ListView1, $a, 1) ;获取要删的列的IP
_GUICtrlListView_DeleteItem($ListView1, $a);删除
;显示离线
GUICtrlSetData($Edit2, $Del_ip & " 离线 - " & @HOUR & ":" & @MIN & ":" & @SEC & @CRLF, "|")
;删除数组
_ArrayDelete($OnlineList, $i)
WinSetTitle($Form1, "", "服务端,共在线:" & UBound($OnlineList) - 1 & " 台机子")
AdlibRegister("_Recv_Dellist");重新启用
ExitLoop ;这个退出用来防止删除过多的socket,如果没有这个可能导致 $recv = TCPRecv($OnlineList[$i][0], "") 这一句数组错误。
EndIf
Next
EndFunc ;==>_Recv_Dellist
Func SocketToIP($SHOCKET)
Local $sockaddr, $aRet
$sockaddr = DllStructCreate("short;ushort;uint;char[8]")
$aRet = DllCall("Ws2_32.dll", "int", "getpeername", "int", $SHOCKET, _
"ptr", DllStructGetPtr($sockaddr), "int*", DllStructGetSize($sockaddr))
If Not @error And $aRet[0] = 0 Then
$aRet = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($sockaddr, 3))
If Not @error Then $aRet = $aRet[0]
Else
$aRet = 0
EndIf
$sockaddr = 0
Return $aRet
EndFunc ;==>SocketToIP
Func _ReduceMemory()
$I_PID = @AutoItPID
Local $ai_Handle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', 0x1f0fff, 'int', False, 'int', $I_PID)
Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', $ai_Handle[0])
DllCall('kernel32.dll', 'int', 'CloseHandle', 'int', $ai_Handle[0])
Return $ai_Return[0]
EndFunc ;==>_ReduceMemory
Func WM_NOTIFY($hWndGUI, $MsgID, $wParam, $lParam)
Local $tagNMHDR, $event, $hwndFrom, $code
$tagNMHDR = DllStructCreate("int;int;int", $lParam)
If @error Then Return
$event = DllStructGetData($tagNMHDR, 3)
If $wParam = $ListView1 And $event = $NM_RCLICK Then
IF _GUICtrlListView_GetSelectedIndices($ListView1) = "" Then
GUICtrlSetState ($menu1, $GUI_DISABLE)
Else
GUICtrlSetState ($menu1, $GUI_ENABLE)
Endif
Endif
$tagNMHDR = 0
$event = 0
$lParam = 0
EndFunc ;==> 在$ListView1中鼠标事件
客户端#notrayicon
; 设置一些常用信息
;--------------------------
Local $ConnectedSocket, $szData
; 设置 $szIPADDRESS 为服务端IP. 这里使用本地的机器名称转换为 IP 地址
; Local $szServerPC = @ComputerName
; Local $szIPADDRESS = TCPNameToIP($szServerPC)
Local $szIPADDRESS =@IPAddress1
Local $nPORT = 33892
; 开始 TCP 服务
;==============================================
TCPStartup()
; 初始化一个变量描述连接
;==============================================
$ConnectedSocket = -1
;尝试连接到服务端IP的 33891 端口.
;=======================================================
While 1
ToolTip($ConnectedSocket & " - 服务端在线,空闲等待接收数据...", 10, 10)
_Recv()
Sleep(300)
WEnd
Func _Recv()
$recv = TCPRecv($ConnectedSocket, 1024 * 50, 1)
If @error Then
_Conn()
Return 0
ElseIf $recv <> "" Then;如果接收不为空
$recv = BinaryToString($recv, 4)
$recv = StringSplit($recv, "|")
If $recv[1] = "Control_Msg" Then
tooltip($recv[2],10,30)
Msgbox(0,0,$recv[2])
EndIf
EndIf
EndFunc ;==>_Recv
Func _Conn()
ToolTip($ConnectedSocket & " - 服务端离线,等待偿试连接中...", 10, 10)
$ConnectedSocket = TCPConnect($szIPADDRESS, $nPORT)
EndFunc ;==>_Conn
|
|