找回密码
 加入
搜索
查看: 681|回复: 18

如何 用TCP实现远程关机、重启

[复制链接]
发表于 2023-10-5 10:09:08 | 显示全部楼层 |阅读模式
如何 用TCP实现远程关机、重启
发表于 2023-10-5 14:48:46 | 显示全部楼层
请附上你的思路和代码,否则没人会理你...


===================
 楼主| 发表于 2023-10-5 16:33:54 | 显示全部楼层
本帖最后由 wllx 于 2023-10-5 17:11 编辑
邪恶海盗 发表于 2023-10-5 14:48
请附上你的思路和代码,否则没人会理你...

#include <MsgBoxConstants.au3>
#include <Array.au3>
#include <StructureConstants.au3>
#include <ListViewConstants.au3>
#include <FileConstants.au3>
#include <StaticConstants.au3>
#include <WinAPIEx.au3>
#include <AutoItConstants.au3>
#include <GUIConstantsEx.au3>
#include <TrayConstants.au3>
#include <file.au3>
#include <winapi.au3>
#include <WindowsConstants.au3>
#include <Constants.au3>
#include <GuiListView.au3>
#include <GuiMenu.au3>
#include <Process.au3>
#include <WinAPIFiles.au3>
_WinAPI_Wow64EnableWow64FsRedirection(False)
 Local $Cofing = @ScriptDir & "\wim\jydn\lan.ini", $fonts = "微软雅黑"
_skins3()
Local $tcpport = 8411, $tcpip = @IPAddress1
Local $_tcp_hsockets[1][10], $recvone = 0, $delsocket = -1, $connectedsocket, $recvtcp = 0
Local $tcprecvmode, $postsk, $mainstr = "####", $recvbtos, $recvold, $error
Local $mainsocket = TCPListen($tcpip, $tcpport)
Local $mht = GUICreate("远程控制", 326, 500)
Local $listview3 = GUICtrlCreateListView("", 10, 10, 306, 480)
_GUICtrlListView_SetTextBkColor($listview3, 6027594)
_GUICtrlListView_AddColumn($listview3, "", 0)
_GUICtrlListView_AddColumn($listview3, "Socket", 0)
_GUICtrlListView_AddColumn($listview3, "客户端名称", 145, 2)
_GUICtrlListView_AddColumn($listview3, "客户端IP地址", 145, 2)
$listMenu = GUICtrlCreateContextMenu($listview3)
$reboot= GUICtrlCreateMenuItem("重启客户端", $listMenu)
GUICtrlSetFont(-1, 9, 400, 1, $fonts)
$boot = GUICtrlCreateMenuItem("关闭客户端", $listMenu)
GUICtrlSetFont(-1, 9, 400, 1, $fonts)
$TightVNC= GUICtrlCreateMenuItem("连接客户端", $listMenu)
GUICtrlSetFont(-1, 9, 400, 1, $fonts)
GUISetState()
TCPStartup()
Local $mainsocket = TCPListen(IniRead($Cofing, "lan", "TCPIP ", ""), $tcpport)
GUIRegisterMsg($wm_command, "WM_NOTIFY")
MyTCP_Server($tcpip, $tcpport)
While 1
        _tcprecv()
        _while()
WEnd

Func _while()
        $nmsg = GUIGetMsg()
        Switch $nmsg
                Case $gui_event_close, $idclose
                        Exit
        EndSwitch
EndFunc   ;==>_While

Func quit()
        TCPShutdown()
        Exit
EndFunc   ;==>quit
Func wm_notify($hwnd, $imsg, $iwparam, $ilparam)
        Local $hwndfrom
        $hwndfrom = $ilparam
        Switch $iwparam
                Case $TightVNC
                        $index = ControlListView($mht, "", "[CLASS:SysListView32; INSTANCE:1]", "GetSelected", 3)
                        If $index <> "" Then
                                $ip = ControlListView($mht, "", "[CLASS:SysListView32; INSTANCE:1]", "GetText", $index, 3)
                                TrayTip("通知", " " &"正在连接" &"☛"& $ip  , 1, 1)
                                Run(@ComSpec & " /c " & @ScriptDir & "\DYsoft\tvnviewer.exe" & " " & $ip, @ScriptDir, @SW_HIDE)
                        EndIf
                        Return True
                Case $reboot
                          $index = ControlListView($mht, "", "[CLASS:SysListView32; INSTANCE:1]", "GetSelected", 3)
                             If $index <> "" Then
                                $ip = ControlListView($mht, "", "[CLASS:SysListView32; INSTANCE:1]", "GetText", $index, 3)
                                TrayTip("通知", " " &"正在重启" &"☛"& $ip  , 1, 1)
                                Run(@ComSpec & ' /c ' & 'shutdown -m \\' & $ip & ' -r -f -t 0', '@ScriptDi', @SW_HIDE)
                        EndIf
                        Return True
        Case $boot
                          $index = ControlListView($mht, "", "[CLASS:SysListView32; INSTANCE:1]", "GetSelected", 3)
                             If $index <> "" Then
                                $ip = ControlListView($mht, "", "[CLASS:SysListView32; INSTANCE:1]", "GetText", $index, 3)
                                TrayTip("通知", " " &"正在关机" &"☛"& $ip  , 1, 1)
                                Run(@ComSpec & ' /c ' & 'shutdown -m \\' & $ip & ' -s -f -t 0', '@ScriptDi', @SW_HIDE)
                        EndIf
                        Return True
        EndSwitch
EndFunc   ;==>wm_notify

Func MyTCP_Server($tcpip, $tcpport)
  Local $iListenSocket = TCPListen($tcpip, $tcpport , 250)
    Local $iError = 0
    If @error Then
        $iError = @error
        Return False
    EndIf
    Local $iSocket = 0
    Do
        $iSocket = TCPAccept($iListenSocket)
        If @error Then
            $iError = @error

            Return False
        EndIf
 If GUIGetMsg() = $GUI_EVENT_CLOSE Then Return False
    Until $iSocket <> -1
    TCPCloseSocket($iListenSocket)
    Local $sReceived = TCPRecv($iSocket, 4)
    TCPCloseSocket($iSocket)
EndFunc   ;==>MyTCP_Server

Func _tcprecv()
        Local $regsocket = -1, $regip, $rdays
        Dim $regsocket = TCPAccept($mainsocket)
        If $regsocket <> -1 Then
                Dim $recv_1 = TCPRecv($regsocket, 1024 * 1024, 1)
                If @error Then
                        $error = Int(@error)
                EndIf
                If $recv_1 <> "" Then
                        $checkdata = StringLeft($recv_1, 12)
                        If $checkdata = "0x232323232B" Then
                                $regip = sockettoip($regsocket)
                                $recvbtos = BinaryToString($recv_1, 4)
                                $rdays = StringSplit($recvbtos, "+", 1)
                                If IsArray($rdays) Then
                                        If UBound($rdays) > 3 Then
                                                If StringUpper($rdays[4]) = StringUpper("SendName") Then
                                                        _socketact($regsocket, $regip, $rdays[5], "SendName")
                                                        Dim $onlinepclist = ""
                                                        For $i = 1 To UBound($_tcp_hsockets) - 1
                                                                $onlinepclist = $onlinepclist & $_tcp_hsockets[$i][0] & "|" & $_tcp_hsockets[$i][2] & ","
                                                        Next
                                                EndIf
                                        EndIf
                                EndIf
                        EndIf
                EndIf
        Else
                If (UBound($_tcp_hsockets)) > 1 Then
                        For $i = 1 To UBound($_tcp_hsockets) - 1
                                Dim $recv_1 = TCPRecv($_tcp_hsockets[$i][0], 1024 * 1024, 1)
                                If @error Then
                                        $error = Int(@error)
                                        If $error = 10054 Then
                                                If $_tcp_hsockets[$i][0] <> -1 Then
                                                        $delsocket = $_tcp_hsockets[$i][0]
                                                        TCPCloseSocket($_tcp_hsockets[$i][0])
                                                EndIf
                                        EndIf
                                EndIf
                                If $recv_1 <> "" Then
                                        $postsk = $_tcp_hsockets[$i][0]
                                EndIf
                        Next
                        If $delsocket <> -1 Then
                                _tcp_server_broadcast($delsocket, "offline")
                        EndIf
                EndIf
        EndIf
EndFunc   ;==>_tcprecv

Func _socketact($socketid = -1, $socketip = "", $socketname = "", $mode = "add")
        If $socketid <> -1 And $socketip <> "" And $socketname <> "" Then
                Dim $name_and_ip = $socketname & "|" & $socketip
                Dim $so_name_and_ip = _ArrayFindAll($_tcp_hsockets, $socketid, 0, 0, 0, 0, 0)
                If IsArray($so_name_and_ip) Then
                        TCPCloseSocket($_tcp_hsockets[$so_name_and_ip[0]][0])
                        $_tcp_hsockets[$so_name_and_ip[0]][0] = $socketid
                        $_tcp_hsockets[$so_name_and_ip[0]][3] = 1
                        Assign("GSocket" & $socketid, $so_name_and_ip[0], 2)
                        _tcp_server_broadcast($socketid, "ONLINE")
                Else
                        Dim $recvubound = UBound($_tcp_hsockets)
                        ReDim $_tcp_hsockets[$recvubound + 1][10]
                        $_tcp_hsockets[$recvubound][0] = $socketid
                        $_tcp_hsockets[$recvubound][1] = $socketip
                        $_tcp_hsockets[$recvubound][2] = $name_and_ip
                        $_tcp_hsockets[$recvubound][3] = 1
                        Assign("GSocket" & $socketid, $recvubound, 2)
                        _tcp_server_broadcast($socketid, "ONLINE")
                EndIf
        EndIf
EndFunc   ;==>_socketact

Func _tcp_server_broadcast($stext = "", $sendtype = "Msg")
        If StringUpper($sendtype) = StringUpper("ONLINE") Or StringUpper($sendtype) = StringUpper("offline") Then
                Dim $stexta = $_tcp_hsockets[Eval("GSocket" & $stext)][0] & "|" & $_tcp_hsockets[Eval("GSocket" & $stext)][2]
                _clientline($stexta, $sendtype)
        Else
                Dim $stexta = $stext
        EndIf
        If (UBound($_tcp_hsockets)) > 1 Then
                Dim $sendmsg = StringToBinary($mainstr & "++0+" & $sendtype & "+" & $stexta & ",+", 4)
                For $i = 1 To UBound($_tcp_hsockets) - 1
                        If StringUpper($sendtype) = StringUpper("ONLINE") Or StringUpper($sendtype) = StringUpper("offline") Then
                                If UBound($_tcp_hsockets) > $i Then
                                        If $_tcp_hsockets[$i][0] And $_tcp_hsockets[$i][0] <> $stext Then
                                                TCPSend($_tcp_hsockets[$i][0], $sendmsg)
                                                If @error Then
                                                        $error = Int(@error)
                                                        If $_tcp_hsockets[$i][0] <> -1 Then
                                                                $delsocket = $_tcp_hsockets[$i][0]
                                                                TCPCloseSocket($_tcp_hsockets[$i][0])
                                                        EndIf
                                                        If $delsocket <> -1 Then
                                                                _tcp_server_broadcast($delsocket, "offline")
                                                        EndIf
                                                EndIf
                                        EndIf
                                EndIf
                        Else
                                If $_tcp_hsockets[$i][0] Then
                                        TCPSend($_tcp_hsockets[$i][0], $sendmsg)
                                        If @error Then
                                                $error = Int(@error)
                                                If $_tcp_hsockets[$i][0] <> -1 Then
                                                        $delsocket = $_tcp_hsockets[$i][0]
                                                        TCPCloseSocket($_tcp_hsockets[$i][0])
                                                        If $delsocket <> -1 Then
                                                                _tcp_server_broadcast($delsocket, "offline")
                                                        EndIf
                                                EndIf
                                        EndIf
                                EndIf
                        EndIf
                Next
                If $delsocket <> -1 Then
                        _ArrayDelete($_tcp_hsockets, Eval("GSocket" & $delsocket))
                        Assign("GSocket" & $delsocket, -1, 2)
                        $delsocket = -1
                EndIf
        EndIf
EndFunc   ;==>_tcp_server_broadcast

Func _clientline($sonlineipstr = "", $sonlinemode = "")
        If $sonlineipstr <> "" Then
                Dim $sonlinesp = StringSplit($sonlineipstr, "|", 1)
                If IsArray($sonlinesp) Then
                        If UBound($sonlinesp) > 3 Then
                                Dim $sonlinesocket = $sonlinesp[1]
                                Dim $sonlinename = $sonlinesp[2]
                                Dim $sonlineip = $sonlinesp[3]
                                Dim $getitemcount = _GUICtrlListView_GetItemCount($listview3)
                                Dim $sonline_id = _GUICtrlListView_FindInText($listview3, $sonlinename & "|" & $sonlineip)
                                If $sonline_id <> -1 Then
                                        If StringUpper($sonlinemode) = StringUpper("offline") Then
                                                TrayTip("通知", " " & $sonlineipstr & "已断开", 1, 1)
                                                _GUICtrlListView_DeleteItem(GUICtrlGetHandle($listview3), $sonline_id)
                                        Else
                                                TrayTip("通知", " " & $sonlinename & "已连接.", 1, 1)
                                                _GUICtrlListView_SetItem($listview3, $sonlinesocket, $sonline_id, 1)
                                        EndIf
                                Else
                                        If StringUpper($sonlinemode) = StringUpper("ONLINE") Then
                                                TrayTip("通知", " " & $sonlinename & "已连接.", 1, 1)
                                                _GUICtrlListView_AddItem($listview3, $sonlinename & "|" & $sonlineip, $getitemcount)
                                                _GUICtrlListView_AddSubItem($listview3, $getitemcount, $sonlinesocket, 1, 1)
                                                _GUICtrlListView_AddSubItem($listview3, $getitemcount, $sonlinename, 2, 1)
                                                _GUICtrlListView_AddSubItem($listview3, $getitemcount, $sonlineip, 3, 1)
                                        EndIf
                                EndIf
                        EndIf
                EndIf
        EndIf
EndFunc   ;==>_clientline

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 _skins3()
        FileInstall("D:\au3\Skin\享受风格.she", @TempDir & "\1.she", 1)
        FileInstall("d:\au3\skin\Skin.dll", @TempDir & "\Skin.dll", 1)
        $skins = @TempDir & "\1.she"
        $Dll = DllOpen(@TempDir & "\Skin.dll")
        DllCall($Dll, "int", "SkinH_AttachEx", "str", $skins, "str", "mhgd")
        FileDelete(@TempDir & "\Skin.dll")
        FileDelete(@TempDir & "\1.she")
EndFunc   ;==>_skins1


本帖子中包含更多资源

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

×
发表于 2023-10-5 18:25:07 | 显示全部楼层
這個目前是我還在寫的,還沒寫完,你可以參考看看,重點是連進去後,透過接收字串,符合指定字串就重啟。
流程,
1.被控端開機後背景常駐,此客戶端需要指定一組固定IP,並啟動 tcp listen,待遠端登入。
2.主控端依list 選擇 tcp connect ,等待被控端回應已連線後(可以用回應字串確認已連線),點擊重啟命令,重起命令可以使用特定字串,如 "real-time-reset" 送至被控端。
3.被控端接收字串後,確認符合 real-time-reset 這字串,立即執行 Shutdown(6)


#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>

Opt("TrayIconHide", 0)                 ;0 = 顯示托盤圖標, 1 = 隱藏托盤圖標
Opt('MustDeclareVars', 1)        ;0 = 變量不需預先聲明, 1 = 變量必需預先聲明
Opt("GUICloseOnESC", 0)         ;0 = 點擊 Esc 鍵不關閉1 = 點擊 Esc 鍵關閉,

;Local $hGUI = GUICreate("BS_SERVICE",150,100,-1,-1)

TCPStartup() ; 启动 TCP 服务.
Local $sIPAddress = "127.0.0.1" ; 此 IP 地址仅用于在您自己的计算机上测试.
Local $iPort = 65432 ; 用于连接的端口.
Global $iListenSocket = TCPListen($sIPAddress, $iPort,5)
If @error Then
        Local $iError = @error
    MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONHAND), "", "監聽失敗,錯誤代碼: " & $iError)
Else
    MsgBox($MB_SYSTEMMODAL, "", "監聽成功.",1)
EndIf
Global $iSocket_1 = -1, $iSocket_2 = 0

Local $sReceived

;GUISetState(@SW_SHOW, $hGUI)

; 循环到用户退出.
While 1
        Switch GUIGetMsg()
                Case $GUI_EVENT_CLOSE
                        TCPCloseSocket($iListenSocket)
                        Sleep(1000)
                        TCPShutdown()
                        ExitLoop
        EndSwitch

        TcpConnListen()

    If $iSocket_1 <> -1 then
                $sReceived = TCPRecv($iSocket_1, 10) ;
                If $sReceived <> "" Then
                        MsgBox(0,"$sReceived",$sReceived,1)
                        If $sReceived =  "RESET" & @CRLF Then
                                TCPSend($iSocket_1,"RESET_OK")
                                TCPCloseSocket($iListenSocket)
                                $sReceived = ""
                                $iSocket_1 = -1
                                $iSocket_2 = -1
                                TCPShutdown()
                        Else
                                $sReceived = ""
                        EndIf
                EndIf
        EndIf
WEnd

Func TcpConnListen()
        Local $iError = ""
        If $iSocket_1 = -1 Then
                If $iSocket_2 = -1 Then
                        TCPStartup()
                        $iListenSocket = TCPListen($sIPAddress, $iPort,5)
                        $iSocket_2 = 0
                EndIf
                $iSocket_1 = TCPAccept($iListenSocket)
                If @error Then
                        $iError = @error
                        MsgBox(BitOR($MB_SYSTEMMODAL, $MB_ICONHAND), "", "服务器:" & @CRLF & "不能接收传入的连接,错误代码: " & $iError)
                EndIf
        EndIf

EndFunc
发表于 2023-10-5 20:52:52 | 显示全部楼层
TCP代码比较复杂,用UDP实现代码会更加简洁。
发表于 2023-10-5 21:02:52 | 显示全部楼层
Global $IPAddress = "127.0.0.1"
Global $Port = 65432
UDPStartup()
MyUDP_Server($IPAddress, $Port)
MsgBox(0, "", "关机")
Exit

Func MyUDP_Server($sIPAddress, $iPort)
        Local $iSocket = UDPBind($sIPAddress, $iPort)
        If @error Then
                Local $iError = @error
                MsgBox(0, "", "服务器:" & @CRLF & "无法绑定,错误代码: " & $iError)
                Return False
        EndIf
        Local $sReceived = ""
        Do
                $sReceived = UDPRecv($iSocket, 4)
        Until $sReceived == "EXIT"
        UDPCloseSocket($iSocket)
EndFunc   ;==>MyUDP_Server
发表于 2023-10-5 21:22:57 | 显示全部楼层
本帖最后由 gyp2000 于 2023-10-5 21:27 编辑

TCP协议实现这种简单的功能就比较复杂了。
需要循环监听传入。然后创建连接套接字,远端断开连接后还需要释放套接字。
还需要做连接是否存活的监测,如果连接异常断开还需要释放套接字资源。
由于使用循环效率低,TCP服务端还会使用事件模式来处理远端连接请求、数据接收、远端断开连接这些事件。
一般没特殊需求,很少用TCP协议来处理这种简单需求。
发表于 2023-10-5 23:15:08 | 显示全部楼层
代码没看,我觉得,服务器给客户机发一个指令代码,比如发一个字符串shut,客户端就执行关机命令,发一个字符串restart,客户端就执行重启命令。当然用整数也可以,比如发一个0x01是关机,发一个0x02是重启。大概思路就这样吧。
 楼主| 发表于 2023-10-6 07:21:26 | 显示全部楼层
haijie1223 发表于 2023-10-5 23:15
代码没看,我觉得,服务器给客户机发一个指令代码,比如发一个字符串shut,客户端就执行关机命令,发一个字 ...

思路不等于出路
这个是人家写的进程监视器服务端

#NoTrayIcon
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=D:\图标\多彩图标\apps\atom.ico
#AutoIt3Wrapper_Outfile=F:\MHT_YS_IPXE\进程监视器服务端.exe
#AutoIt3Wrapper_Res_Comment=进程监视器服务端
#AutoIt3Wrapper_Res_Description=进程监视器服务端
#AutoIt3Wrapper_Res_Fileversion=1.0.0.7
#AutoIt3Wrapper_Res_Fileversion_AutoIncrement=y
#AutoIt3Wrapper_Res_LegalCopyright=L4EVER QQ:425145
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#NoTrayIcon
#Region ;**** 参数创建于 ACNWrapper_GUI ****
#EndRegion ;**** 参数创建于 ACNWrapper_GUI ****

#Include <GuiListView.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
#include <GuiIPAddress.au3>
#include "TCP.au3"
#include <WinAPIFiles.au3>
_WinAPI_Wow64EnableWow64FsRedirection(False)
Local $Cofing = @ScriptDir & "\wim\jydn\lan.ini"
_SKIN()
Writelog("信息","程序启动,打开5138端口,并监听.")
_TCP_Server_Create(5138); 一个新的服务端
_TCP_RegisterEvent($TCP_RECEIVE, "Receive");收到数据
_TCP_RegisterEvent($TCP_NEWCLIENT, "NewClient");客户端上线
Local $itemcount3
Global $GUICLOSE=1,$NEXT="NONE",$WATING=0,$Message=0,$LOCALIP=@IPAddress1,$Connected=-1,$REMOTEIP=1

$GUI=GUICreate("远控服务端",410,500)
$listview = GUICtrlCreateListView("       机器名|        IP地址|         提示|             上线时间", 5, 5, 400,490)
GUICtrlSetFont(-1, 8.5, 400, 0, "微软雅黑")
_GUICtrlListView_SetColumnWidth($listview, 0, 80)
_GUICtrlListView_SetColumnWidth($listview, 1, 100)
_GUICtrlListView_SetColumnWidth($listview, 2, 80)
_GUICtrlListView_SetColumnWidth($listview, 3, 130)
$listMenu = GUICtrlCreateContextMenu($listview)
$clsj = GUICtrlCreateMenuItem("退出", $listMenu)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
$cqgj = GUICtrlCreateMenuItem("重启", $listMenu)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
$gbgj = GUICtrlCreateMenuItem("关闭", $listMenu)
GUICtrlSetFont(-1,9, 400, 0, "微软雅黑")
$scgx = GUICtrlCreateMenuItem("删除", $listMenu)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
$TightVNC= GUICtrlCreateMenuItem("连接", $listMenu)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
GUISetState()

Func Receive($iError, $sreceive)
        $str = StringReplace($sreceive,"KILLED","已上线")
        Writelog("信息","收到客户端发送的报告,内容:"&$str)
        GUICtrlCreateListViewItem($str&"|"&@YEAR & "-" & @MON & "-" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC,$listview)
        Beep(1000, 500)
EndFunc

Func NewClient()
        Writelog("信息","客户端上线")
EndFunc

_GUICtrlListView_RegisterSortCallBack($listview)
While $GUICLOSE
        Sleep(10)
        $GUI=GUIGetMsg()
        If $GUI=$GUI_EVENT_CLOSE Then $GUICLOSE=0
        If $GUI=$clsj Then
                        _send2client("RESET")
        EndIf

                 If $GUI=$cqgj Then
            _TCP_Server_Send("RESTART")
                         GUICtrlDelete(GUICtrlRead($listview))
                         GUICtrlSetData($itemcount3,"待处理事件:"&_GUICtrlListView_GetItemCount($listview))
        EndIf

                 If $GUI=$gbgj Then
            _TCP_Server_Send("SHUT")
                         GUICtrlDelete(GUICtrlRead($listview))
                         GUICtrlSetData($itemcount3,"待处理事件:"&_GUICtrlListView_GetItemCount($listview))
                 EndIf
                 If $GUI=$scgx Then
            GUICtrlDelete(GUICtrlRead($listview))
                        GUICtrlSetData($itemcount3,"待处理事件:"&_GUICtrlListView_GetItemCount($listview))
                EndIf
                If $GUI=$listview Then
                 _GUICtrlListView_SortItems($listview, GUICtrlGetState($listview))
         EndIf
        WEnd

Func _send2client($str)
        Writelog("信息","响应人工操作,开始处理.")
        $listteam = StringSplit(GUICtrlRead(GUICtrlRead($listview)),"|")
                        If Not @error Then
                        $clientip = $listteam[2]
                        Writelog("信息","选中的时间发生时间:"&$listteam[4]&",目标机器:["&$listteam[1]&"]"&$clientip&",事件:"&$listteam[3])
                Else
                        Writelog("错误","人工操作失败,可能是没选中列表内的项目.")
                        MsgBox(16,"错误","请从列表中选中项目再操作.")
                        $clientip =""
                EndIf
If $clientip<> "" Then
        TCPStartup()
        $Connected=TCPConnect($clientip,5139)
        If Not ($Connected > 0) Or @error then
                Writelog("错误","连接"&$clientip&"失败,错误代码:"&@error)
                        Else
                                Writelog("信息","连接"&$clientip&"成功.SocketID:"&$Connected)
                        EndIf

        $sendresult = TCPSend($Connected,$str)
        If $sendresult ="0" Or @error Then
                        Writelog("错误","发送命令"&$str&"到"&$clientip&"失败,错误代码:"&@error)
                        Else
                Writelog("信息","发送命令"&$str&"到"&$clientip&"成功.")
                GUICtrlDelete(GUICtrlRead($listview))
                GUICtrlSetData($itemcount3,"待处理事件:"&_GUICtrlListView_GetItemCount($listview))
        EndIf
EndIf
TCPShutdown()
Writelog("信息","关闭对该机的连接.")
Writelog("信息","响应人工操作完成.")
EndFunc

Func _SKIN()
        $pf = IniRead($Cofing, "PF", "PF", "")
        $skins = @ScriptDir & "\Skin\" & $pf
        $Dll = DllOpen(@ScriptDir & "\Skin\Skin.dll")
        DllCall($Dll, "int", "SkinH_AttachEx", "str", $skins, "str", "mhgd")
        DllCall($Dll, "int", "SkinH_SetAero", "int", 1)
EndFunc   ;==>_skins

Func Writelog($logact,$logcontent)
        $Logfile= @ScriptDir &"\"& StringTrimRight(@ScriptName,4)&".log"
        $Logtime = @YEAR & "-" & @MON & "-" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC &"." &@MSEC
        FileWriteLine($Logfile,  $Logtime & " | " & $logact & " | " & $logcontent)
EndFunc

############
客户端:

;~ #NoTrayIcon
#Region ;**** 参数创建于 ACNWrapper_GUI ****
#AutoIt3Wrapper_icon=c:\Windows\system32\SHELL32.dll
#AutoIt3Wrapper_outfile=进程监视器.exe
#AutoIt3Wrapper_Res_Comment=进程监视器
#AutoIt3Wrapper_Res_Description=进程监视器
#AutoIt3Wrapper_Res_Fileversion=1.0.0.5
#AutoIt3Wrapper_Res_Fileversion_AutoIncrement=y
#AutoIt3Wrapper_Res_LegalCopyright=L4EVER QQ:425145
#EndRegion ;**** 参数创建于 ACNWrapper_GUI ****
#include "TCP.au3"
Global $server = IniRead(@ScriptDir &"\lan.ini", "lan", "TCPip","")
Global $process = IniRead(@ScriptDir &"\lan.ini", "lan", "进程","")
Global $htime = IniRead(@ScriptDir &"\lan.ini", "lan", "循环时间","")
Global $GUICLOSE=1,$WATING=0,$Message=0,$LOCALIP=@IPAddress1,$Connected=-1,$connok=0,$pcheckalert=0

If $server ="" Or $process ="" Then
        Writelog("错误","配置错误,程序退出,请检查配置.")
        MsgBox(0+16,"错误","配置错误,请检查配置,程序3秒后自动退出。",3)
        exit
EndIf

Global $g_szVersion = "processkeeper"
If WinExists($g_szVersion) Then Exit
AutoItWinSetTitle($g_szVersion)

Writelog("信息","程序启动,开始尝试连接服务端")
connserver()
Writelog("信息","开始进行巡检检测,间隔时间为"&$htime&"毫秒")

If $connok = 1 Then AdlibRegister("_pcheck",$htime)

While 1
        Sleep(900)
        $command=TCPRecv($Connected,2048)
        If $command <> "" Then
                Writelog("信息","接收到服务端命令:"&$command)
                runcommand($command)
                $command = ""
        EndIf

WEnd

Func runcommand($str1)
        Writelog("信息","处理服务端发送的命令"&$str1)
        Switch $str1
                Case "RESET"
                        Writelog("信息","服务端要求初始化客户端程序,开始执行.")
                        connserver()
                        If $connok = 1 Then AdlibRegister("_pcheck",$htime)
                Case "RESTART"
                        Writelog("信息","服务端要求重启客户机,开始执行.")
                        Shutdown(6)
                        Writelog("信息","服务端要求关闭客户机,开始执行.")
                Case "SHUT"
                        Shutdown(5)
        EndSwitch

        EndFunc

Func connserver()
        TCPStartup()
        $Connected=TCPConnect($server,5138)
        If Not ($Connected > 0) Or @error then
                Writelog("错误","连接服务端失败,2秒后重试.错误代码:"&@error)
                                TCPShutdown()
                                Sleep(2000)
                                connserver()
                                If $connok = 1 Then AdlibRegister("_pcheck",$htime)
                        Else
                                Writelog("信息","连接服务端成功.SocketID:"&$Connected)
                                Global $connok = 1
        EndIf
EndFunc

Func _pcheck()
If Not ProcessExists($process) Then
                Writelog("信息","客户端巡检检测发现异常,休眠2秒再次检测.")
                Sleep(2000)
                If Not ProcessExists($process) Then
                        Writelog("信息","客户端巡检检测异常确认,开始向服务端发送报告.")
                        _senddata("KILLED")
                        Writelog("信息","停止客户端巡检检测.")
                        AdlibUnRegister("_pcheck")
                        _waitconn()
                EndIf
EndIf

        EndFunc

Func _senddata($str)
                $sendresult = TCPSend($Connected,@ComputerName&"|"&$LOCALIP&"|"&$str)
                        If $sendresult ="0" Or @error Then
                                Writelog("错误","向服务端发送报告失败,错误代码:"&@error)
                                connserver()
                        Else
                                Global $sendresult = 1
                                Writelog("信息","向服务端发送报告成功")
                        EndIf
EndFunc

Func Writelog($logact,$logcontent)
        $Logfile= @ScriptDir &"\"& StringTrimRight(@ScriptName,4)&".log"
        $Logtime = @YEAR & "-" & @MON & "-" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC &"." &@MSEC
        FileWriteLine($Logfile,  $Logtime & " | " & $logact & " | " & $logcontent)
EndFunc

Func _waitconn()
        Writelog("信息","转换模式,等待服务端处理.")
        _TCP_Server_Create(5139); 一个新的服务端
        _TCP_RegisterEvent($TCP_RECEIVE, "Receivec");收到数据
EndFunc

Func Receivec($iError, $sreceive)
        Writelog("信息","收到服务端发送的数据:"&$sreceive)
        runcommand($sreceive)
EndFunc

,这个就能关机重启,但是我不知道方法加入我的代码中

发表于 2023-10-6 15:27:08 | 显示全部楼层
wllx 发表于 2023-10-6 07:21
思路不等于出路
这个是人家写的进程监视器服务端

这个好像我的风格呢。
 楼主| 发表于 2023-10-6 15:36:37 | 显示全部楼层
绿色风 发表于 2023-10-6 15:27
这个好像我的风格呢。



天下代码 一个样,这个是论坛一位同志写的进程监视器,老大,有没有办法套用一下他的关机、重启代码?
发表于 2023-10-6 17:54:09 来自手机 | 显示全部楼层
TCP通讯还存在数据包粘连和数据包截断的问题。虽然短小数据包出现这种问题的概率比较低。如果没有成熟的解决方案,这种问题也不能忽略。
发表于 2023-10-6 20:56:46 来自手机 | 显示全部楼层
TCP来实现远程关机重启,相当于杀鸡用牛刀。AU3内置指令只能实现部分TCP服务器功能。也没成熟的UDF。想实现功能只能自己造轮子。
 楼主| 发表于 2023-10-6 21:23:37 | 显示全部楼层
gyp2000 发表于 2023-10-6 20:56
TCP来实现远程关机重启,相当于杀鸡用牛刀。AU3内置指令只能实现部分TCP服务器功能。也没成熟的UDF。想实现 ...

你没注意到 上面那个进程监视器的代码就实现了远程关机,重启、指令客户端退出
发表于 2023-10-7 19:20:37 来自手机 | 显示全部楼层
人家的代码调用UDF,贴出来的代码部分基本看不出TCP有关的部分。TCP服务器本身不难,比较难处理的是粘包的分离,和无效连接清理。最后就是代码效率问题。
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-5-1 23:24 , Processed in 0.083858 second(s), 21 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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