找回密码
 加入
搜索
查看: 10448|回复: 25

[网络通信] 【已解决】如何通过 TCPSend() 发送 ctrl+c 给远程终端

 火.. [复制链接]
发表于 2011-2-24 15:21:07 | 显示全部楼层 |阅读模式
本帖最后由 xiehuahere 于 2011-3-11 09:49 编辑

如题。
目前已实现通过在23端口建立socket连接来模拟telnet会话,并远程执行脚本,获取回显显示到Edit控件中。但有些脚本出于某种目的,需要死循环执行,想实现点击“Terminate”按钮发送ctrl+c终止脚本运行。
ctrl+c 是不可见字符,如何发送?
尝试多次未果,特来请教。
发表于 2011-2-26 04:51:58 | 显示全部楼层
被控端的所有执行操作都写成函数.
设置一个全局数组,任务队排指令及其参数

使用while 1 循环做_Main,有任务时执行,无任务时空循环.

做一个专门监听端口信息的函数,使用AdlibRegister注册.此函数只接收指令,比如"_复制文件|C:\1|D"
设置一个全局变量,定义一个指定比如收到 "Break",则使此全局变量设置为1
在操作的函数里面,检测这个中断变量,如果要求中断,则Return
 楼主| 发表于 2011-3-2 19:54:39 | 显示全部楼层
谢谢你的回答。
忙了几天,今天才有空上来看一下。
我最后是这样做的:用TCPSend()直接发送 killall 命令杀进程了,因为进程名是固定的形式,“/bin/sh /目录/脚本名”。
发表于 2011-3-2 20:05:33 | 显示全部楼层
这应该很简单啊,死循环脚本里弄一个热键专门执行中止循环。当接收到指定的字符串时,触发这个热键不就行了吗
发表于 2011-3-3 13:19:21 | 显示全部楼层
学习,学习....
 楼主| 发表于 2011-3-3 15:44:07 | 显示全部楼层
回复 4# manlty

我在远程终端上执行是Linux shell脚本。而且脚本不固定,也可能不是我自己写的。
我的工具只负责把脚本从Windows端上载到Linux端并远程控制执行和终止,不能要求在别人的脚本里专门为我的功能加一些东西。
发表于 2011-3-5 09:13:52 | 显示全部楼层
tcp客户端是你写的吧?里面不可以加一些按照指令模拟键盘操作吗
 楼主| 发表于 2011-3-5 19:38:50 | 显示全部楼层
对,TCP客户端是我写的。客户端在Windows侧,Server端在Linux侧。
我不能改server端的东西。
发表于 2011-3-6 12:50:27 | 显示全部楼层
能不能把源码发上来看看呢
发表于 2011-3-6 12:53:12 | 显示全部楼层
server端用C写,client端au3写且TCP,发指令调用相应远程脚本执行,终止运行脚本同理。
发表于 2011-3-8 00:03:50 | 显示全部楼层
你搞错对象了
ctrl+c并不是发送到远程,而是发送到telnet的console本身
 楼主| 发表于 2011-3-8 16:57:06 | 显示全部楼层
本帖最后由 xiehuahere 于 2011-3-8 17:04 编辑

源码有点长,请大家继续帮忙,谢谢 ;-)
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <FTPEx.au3>

Opt("GUIOnEventMode", 1)

Const $user = "root", $passwd = ""
Global $host = "", $socket = "", $port = 23        ;Default port for Telnet
Global $filename = "", $isRunning = 0

Dim $width = 398, $height = 486

#Region ### START Koda GUI section ###
$Form1 = GUICreate("Firmware Script Proxy", $width, $height, (@DesktopWidth - $width) / 2, (@DesktopHeight - $height) / 2, $WS_CAPTION)
$Edit1 = GUICtrlCreateEdit("", 8, 8, 377, 385, BitOR($ES_AUTOVSCROLL,$ES_AUTOHSCROLL,$ES_READONLY,$ES_WANTRETURN,$WS_HSCROLL,$WS_VSCROLL,$WS_BORDER))
GUICtrlSetData(-1, '1. Make sure that device is connected and powered on.' & @CRLF _
                                & '2. Select a script file on local computer.' & @CRLF _
                                & '3. Click "Execute" button to upload it to device and run remotely.')
$Edit2 = GUICtrlCreateEdit("", 16, 407, 281, 24, BitOR($ES_AUTOVSCROLL,$ES_AUTOHSCROLL))
$Button1 = GUICtrlCreateButton("Browse...", 312, 405, 65, 28)
GUICtrlSetOnEvent(-1, "OpenFile")
$Button2 = GUICtrlCreateButton("Execute", 16, 442, 161, 33, $WS_GROUP)
GUICtrlSetOnEvent(-1, "ExecuteScript")
$Button3 = GUICtrlCreateButton("Terminate", 209, 442, 73, 33, $WS_GROUP)
GUICtrlSetOnEvent(-1, "TerminateScript")
GUICtrlSetState(-1, $GUI_DISABLE)
$Button4 = GUICtrlCreateButton("Exit", 307, 442, 73, 33)
GUICtrlSetOnEvent(-1, "ExitEvent")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1
        Sleep(10)
WEnd

Func OpenFile()
        $var = FileOpenDialog("Open", "", "Shell Scripts (*.*)", 1, '', $Form1)
        If @error Then
                ;MsgBox(4096, "Warning", "No File is chosen!")
        Else
                ;MsgBox(4096, "", $var)
                GUICtrlSetData($Edit2, $var)
        EndIf
EndFunc   ;==>OpenFile

Func ExecuteScript()
        control_state_running_script()

        ;Check if a script file is selected
        $filepath = GUICtrlRead($Edit2)
        If $filepath = "" Then
                MsgBox(48, "Error", "Please select a file first.", Default, $Form1)
                control_state_not_running_script()
                Return 1
        Else
                $filename = StringTrimLeft($filepath, StringInStr($filepath, "", 1, -1))
        EndIf

        ;Check device connection
        GUICtrlSetData($Edit1, "Checking connection ...... ")
        $host = get_ip()
        If $host = "" Then
                MsgBox(48, "Error", "device connection not detected!", Default, $Form1)
                GUICtrlSetData($Edit1, "Not detected!" & @CRLF, -1)
                Return 1
        EndIf
        GUICtrlSetData($Edit1, "OK" & @CRLF, -1)

                ;Upload the selected script file to device
        GUICtrlSetData($Edit1, "Uploading file to device ...... ", -1)        
        If ftp_put_file($filepath, "/taurus/" & $filename) Then
                MsgBox(48, "Error", "Upload file to device failed!" & @CRLF)
                GUICtrlSetData($Edit1, "Fail!" & @CRLF, -1)
                control_state_not_running_script()
                Return 1
        EndIf
        GUICtrlSetData($Edit1, "OK" & @CRLF & @CRLF, -1)

        GUICtrlSetData($Edit1, "=====================   Start Telnet Session  =====================" & @CRLF & @CRLF, -1)
        TCPStartup()
        $socket = TCPConnect($host, $port)
        If $socket = -1 Then
                MsgBox(48, "Error", "Connection fail!")
                TCPShutdown()
                control_state_not_running_script()
                Return 1
        EndIf

        $isRunning = 1
        $ret = exec_script()
        TCPCloseSocket($socket)
        TCPShutdown()
        $isRunning = 0
        control_state_not_running_script()
        Return 0
EndFunc   ;==>ExecuteFile

Func TerminateScript()
;~         ;Open another telnet session
;~         $sk = TCPConnect($host, $port)
;~         If $sk = -1 Then
;~                 MsgBox(48, "Error", "Connection fail!", Default, $Form1)
;~                 Return 1
;~         EndIf

;~         TCPSend($sk, 'kill -9 "/bin/sh /taurus/' & $filename & '"' & @CRLF)
;~         ;TCPSend($sk, 'kill -9 $(ps|grep "' & $filename & '"' & "|grep -v grep|awk '{print $1}')" & @CRLF)
;~         wait_cmd_prompt($sk, "#")
;~         TCPCloseSocket($socket)
;~         TCPCloseSocket($sk)
;~         TCPShutdown()

        ;Terminate the session and the running script will also be terminated
        TCPCloseSocket($socket)
        TCPShutdown()

        $isRunning = 0
        control_state_not_running_script()
        Return 0
EndFunc   ;==>ExecuteFile

Func ExitEvent()
        If $isRunning Then
                TerminateScript()
        EndIf
        Exit 0
EndFunc   ;==>ExitEvent


;==================================================================
; Description: Give executable property to the script and execute.
; Return value: Result of the execution.
;                                0 - Successful
;                                1 - Failed
;==================================================================
Func exec_script()
        $delay = 300 ; compensates network/internet delays

        Sleep($delay)
        wait_cmd_prompt($socket, "login")
        TCPSend($socket, $user & @CRLF)
        Sleep($delay)
        If wait_cmd_prompt($socket, "#") Then Return 1
        TCPSend($socket, "chmod a+x /taurus/" & $filename & @CRLF)
        wait_cmd_prompt($socket, "#")
        TCPSend($socket, "/taurus/" & $filename & @CRLF)
        wait_cmd_prompt($socket, "#")
        ;WinSetState($Form1, "", @SW_HIDE)
        Return 0
EndFunc


;==================================================================
; Description: Get IP address of device.
; Return value: A string of IP address.
;==================================================================
Func get_ip()
        Local $oIP = ""
        $strComputer = "."
        $objWMIService = ObjGet("winmgmts:\" & $strComputer & "\root\CIMV2")
        $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration", "WQL")
        For $objItem In $colItems
                If StringInStr($objItem.Description, "Taurus") > 0 And $objItem.IPAddress <> "" Then
                        $oIP = $objItem.IPAddress(0)
                        ExitLoop
                EndIf
        Next

        If $oIP <> "" Then
                $oIP = StringTrimRight($oIP, 2) & "11"   ; Convert PC IP to device IP
        EndIf
        ;MsgBox(0, "IP Address", $oIP)
        Return $oIP
EndFunc


;==================================================================
; Description: Wait for desired output before sending.
; Return value: 0 - Successful
;                1 - Failed
;==================================================================
Func wait_cmd_prompt($sk, $waitStr)
        Local $ack, $count=0

        If $waitStr = "#" Then
                Do
                        $ack = TCPRecv($sk, 300)
                        GUICtrlSetData($Edit1, $ack, -1)
                        $ack = StringStripWS($ack, 2)
                        $count += 1
                        Sleep(300)
                Until StringRight($ack, 1) = "#"

        ElseIf $waitStr = "login" Then
                Do
                        $ack = TCPRecv($sk, 300)
                        GUICtrlSetData($Edit1, $ack, -1)
                        $count += 1
                        If $count = 5 Then
                                MsgBox(48, "Error", 'Wait for prompt "' & $waitStr & '" timeout!' & @CRLF & "Please retry!")
                                Return 1
                        EndIf
                        Sleep(300)
                Until StringInStr($ack, $waitStr) > 0
        EndIf

        Return 0
EndFunc


;==================================================================
; Description: Upload the selected shell script to device.
; Return value: 0 - Successful
;                1 - Failed
;==================================================================
Func ftp_put_file($srcFilePath, $DesFilePath)
        $Open = _FTP_Open('myFTP')
        $ftpConn = _FTP_Connect($Open, $host, $user, $passwd)
        _FTP_FilePut($ftpConn, $srcFilePath, $DesFilePath)
        If @error <> 0 Then
                _FTP_Close($Open)
                Return 1
        EndIf

        _FTP_Close($Open)
        Return 0
EndFunc

Func control_state_running_script()
        GUICtrlSetState($Edit2, $GUI_DISABLE)
        GUICtrlSetState($Button1, $GUI_DISABLE)
        GUICtrlSetState($Button2, $GUI_DISABLE)
        GUICtrlSetState($Button3, $GUI_ENABLE)
EndFunc

Func control_state_not_running_script()
        GUICtrlSetState($Edit2, $GUI_ENABLE)
        GUICtrlSetState($Button1, $GUI_ENABLE)
        GUICtrlSetState($Button2, $GUI_ENABLE)
        If BitAND(GUICtrlGetState($Button3), $GUI_ENABLE) = $GUI_ENABLE Then GUICtrlSetState($Button3, $GUI_DISABLE)
EndFunc
1)如何让脚本正在运行的时候,该工具也能响应“Terminate”与“Exit”按钮?
2)如何去除Edit1中显示的光标?(文本就插入到光标之后,若在脚本运行过程中不断有回显,点击鼠标使光标位置发生改变,就会使得显示的文本变得混杂)

多谢帮忙!
发表于 2011-3-8 23:21:37 | 显示全部楼层
晕,你这是telnet还是ssh啊?
 楼主| 发表于 2011-3-9 13:21:39 | 显示全部楼层
本帖最后由 xiehuahere 于 2011-3-9 13:28 编辑

telnet 啊,23端口主要用于Telnet(远程登录)服务。SSH默认端口貌似是22。
通过在23端口建立socket连接来模拟一个telnet通信。
厄。。。版主有疑问?
发表于 2011-3-9 14:26:28 | 显示全部楼层
嗯,我明白了.
如果是这样,你得先去了解telnet长什么样子.
不过,据我所知,linux下control键是写作"^",你可以试试发送:^C
不行的话再试试用vkey的方式.
当然,最好的方法是抓包.
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-5-17 02:36 , Processed in 0.085578 second(s), 23 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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