[Telnet]关于通过TCP来执行telnet命令从返回值判断是否成功问题.
本帖最后由 小熵 于 2012-9-11 09:36 编辑呼叫 olala,呼叫pcbar,呼叫各位大神...
另外一类似问题
http://www.autoitx.com/forum.php?mod=viewthread&tid=9812&highlight=telnet
在论坛看了TCPsend来进行Telnet,按照一下代码进行之后,提示4个问号,并提示"Cannot connect2"
使用au3检测返回信息的是什么弄的?一部分吗?(If StringInStr($ack, "login:") >= 1 Then ;)
用CMD做telnet之后提示
CentOS Linux release 6.0 (Final)
Kernel 2.6.32-71.el6.i686 on an i686
login:
登录之后提示
Last login: Mon Sep 10 16:34:06 from 172.28.101.1
-bash: /sbin:/usr/sbin:/usr/local/sbin:/usr/kerberos/sbin: 没有那个文件或目录
$
au3代码Global $host, $port, $delay, $user, $pass, $sk, $ack
$host = "172.28.101.9";交换机IP
$port = 23;telnet默认端口
$delay = 500 ; 等待时间/毫秒
$user = "test";用户名
$pass = "123456";密码
TCPStartup()
$sk = TCPConnect($host, $port)
If $sk = -1 Then
MsgBox(0, "", "Cannot connect1")
Exit
EndIf
Sleep($delay)
$ack = TCPRecv($sk, 150)
TrayTip("", $ack, 10)
MsgBox (0,"",$ack)
If StringInStr($ack, "login:") >= 1 Then ;如果连接成功,设备返回有关信息
;下面将发送用户名
Sleep($delay)
TCPSend($sk, "y" & @CRLF)
Sleep($delay)
TCPSend($sk, $user & @CRLF)
Sleep($delay)
$ack = TCPRecv($sk, 80)
TrayTip("", $ack, 10)
; 和密码
Sleep($delay)
TCPSend($sk, $pass & @CRLF)
Sleep($delay)
$ack = TCPRecv($sk, 80)
TrayTip("", $ack, 10)
Else
MsgBox(0, "", "Cannot connect2")
Exit
EndIf
If StringInStr($ack, "$") = 0 Then ; 登陆成功后设备返回的信息
MsgBox(0, "Error", "Access denied")
Exit
EndIf
; 下面你可以发送一些命令给设备,比如重启
Sleep($delay)
TCPSend($sk, "dir" & @CRLF)
Sleep($delay)
$ack = TCPRecv($sk, 2000)
MsgBox(0,"Running processes", $ack)
TCPCloseSocket($sk)
TCPShutdown()
Exit
本帖最后由 xiehuahere 于 2012-9-11 09:34 编辑
回复 1# 小熵
一直在用,所以封装了两个函数SendLine和WaitFor。
本来想发到UDF区的,不过之前发了个FTP的UDF没多少人感兴趣,看来这里跟网络设备打交道的人比较少。所以直接贴这里吧。
试试,有问题反馈。不过我估计应该没什么问题了,毕竟经过了我们可靠性测试几百万次的验证。
不过对于发送命令的最大长度没试验过,一般命令都不会很长,过长的我都封装到shell脚本中然后再用SendLine调用脚本远程执行了。
Global $buff; to hold the received content
;=================================================================
; Name: SendLine
; Description: Send one command line (@CRLF added automatically)
; Return value: 0 - Success
; -1 - Failure
;=================================================================
Func SendLine($string)
TCPSend($socket, $string & @CRLF)
If @error Then
;Local $result = DllCall("Ws2_32.dll", "int", "WSAGetLastError")
;Return $result
Return -1
EndIf
Return 0
EndFunc
;=================================================================
; Name: WaitFor
; Description: Wait for desired output. Use it after each TCPSend() to make
; buff always hold the latest content
; Return value: 0 - Success
; -1 - Failure
;=================================================================
Func WaitFor($string, $timeout=2000)
Local $recv = ""
$buff = ""
If $string <> "" Then
$timer = TimerInit()
Do
$recv &= TCPRecv($socket, $buffSize)
If @error <> 0 Then Return -1
If $recv == "" Then
Sleep(20)
Else
$buff &= $recv
EndIf
If TimerDiff($timer) > $timeout Then Return -1
Until StringInStr($buff, $string) > 0
EndIf
Return 0
EndFunc 本帖最后由 xiehuahere 于 2012-9-11 09:24 编辑
Init函数和_CleanOnExit函数,建立和释放设备连接用。
Local Const $username = "root", $password = "123456"
Local $server, $socket = -1
Local $buff = "", $buffSize = 500;for receiving ack
OnAutoItExitRegister("_CleanOnExit")
Func Init()
TCPStartup()
$socket = TCPConnect($server, 23) ; 23 - telnet port
If @error Then Return -1
; Verify if it's login request
If WaitFor("login") = -1 Then Return -1
;Send username
If SendLine($username) = -1 Then Return -1
If WaitFor("assword") = -1 Then
;Handle the case that password is removed
If StringInStr($buff, "# ") = 0 Then
$needPW = False
Else
Return -1
EndIf
EndIf
If $needPW Then
;Send password
If SendLine($password) = -1 Then Return -1
If WaitFor("# ") = -1 Then Return -1
EndIf
Return 0
End Func
Func _CleanOnExit()
If $socket <> -1 Then TCPCloseSocket($socket)
TCPShutdown()
EndFunc FTP的还好点,FTP可以用-s参数执行写在文本文件里面的命令.. 本帖最后由 小熵 于 2012-9-11 08:57 编辑
看了一下,还是有点摸不着头脑,不知道把这2段加在哪里...好像在上面定义的是$sk,你在函数里面定义的是$soket
其实我就是想telnet到一台服务器上,登录,输入一个show的命令,然后从返回的字符串中间截取一个值,查看是否大于60,如果大于60,就执行一条命令,如果没有达到60,则继续循环检查这个值...
telnet ip之后返回的是
CentOS Linux release 6.0 (Final)
Kernel 2.6.32-71.el6.i686 on an i686
login:
登录之后返回的是
Last login: Mon Sep 10 16:46:10 from 172.28.101.105
$
执行查询命令返回的是:
abc 62
这个62大于60,所以执行一条命令
要求后台执行,不影响用户操作.. 本帖最后由 xiehuahere 于 2012-9-11 09:30 编辑
$sk和$socket只是变量名的区别,自己改改就是了。
执行命令用SendLine函数;接收返回内容用WaitFor函数(等待感兴趣的字符串,你这里如abc),接收到的字符串存在$buff这个全局变量中。(见2#)
如果接收超时,WaitFor函数会返回-1。
每次SendLine后用WaitFor将内容收走,以保证此后每次接收的都是最新内容。(使用示例见3#)
你这里的命令提示符是“$”(非root权限),所以你在接收时要用"$ "来代替我代码中的"# "(之所以后面加个空格是为了防止你的命令输出中也含有这个字符,以免跟命令提示符混淆)。
你用MsgBox或ConsoleWrite将WaitFor收到的内容打印出来看。然后用字符串处理函数自己处理,截取自己想要的内容。
好了,方法就这些,示例代码也有了。剩下靠自己,有问题再来问~~ 好的,我自己在研究琢磨琢磨
不懂再来请教..
我的感觉是跟网络设备打交道又懂得编程的人太少了.. 好的,我自己在研究琢磨琢磨
不懂再来请教..
我的感觉是跟网络设备打交道又懂得编程的人太少了.. 回复 6# xiehuahere
我按照你的提示写了一段,大致的思路是定义server ,sername,password,然后用init()开始telnet,用sendline发送命令,用waitfor检测返回,用cleanOnExit退出
但是我不明白autoit的函数调用
我把server改成了101.900,明显是不对的,但是我运行总是提示如果telnet返回不是-1,就关闭tcp连接
用户名也是错的..还请指导,谢谢Local Const $username = "fanfang", $password = "123456"
Local $server, $socket = -1
$server = "172.28.101.900";服务器IP
Local $buff = "", $buffSize = 500;for receiving ack
OnAutoItExitRegister("_CleanOnExit")
Func Init()
TCPStartup()
$socket = TCPConnect($server, 23) ; 23 - telnet port
If @error Then Return -1
MsgBox(0,"","服务器连接出错")
; Verify if it's login request
If WaitFor("login") = -1 Then Return -1
MsgBox(0,"","没有找到用户名输入点")
;Send username
If SendLine($username) = -1 Then Return -1
MsgBox(0,"","用户名发送出错")
If WaitFor("password") = -1 Then
;Handle the case that password is removed
If StringInStr($buff, "# ") = 0 Then
$needPW = False
MsgBox(0,"","不需要密码")
Else
Return -1
MsgBox(0,"","没有找到密码输入点")
EndIf
EndIf
If $needPW Then
;Send password
If SendLine($password) = -1 Then Return -1
MsgBox(0,"","密码发送失败")
If WaitFor("# ") = -1 Then Return -1
MsgBox(0,"","这里是干什么?????????")
EndIf
Return 0
EndFunc
Global $buff; to hold the received content
$string="ps"
;=================================================================
; Name: SendLine
; Description: Send one command line (@CRLF added automatically)
; Return value: 0 - Success
; -1 - Failure
;=================================================================
Func SendLine($string)
TCPSend($socket, $string & @CRLF)
If @error Then
;Local $result = DllCall("Ws2_32.dll", "int", "WSAGetLastError")
;Return $result
Return -1
EndIf
Return 0
EndFunc
;=================================================================
; Name: WaitFor
; Description: Wait for desired output. Use it after each TCPSend() to make
; buff always hold the latest content
; Return value: 0 - Success
; -1 - Failure
;=================================================================
Func WaitFor($string, $timeout=2000)
Local $recv = ""
$buff = ""
If $string <> "" Then
$timer = TimerInit()
Do
$recv &= TCPRecv($socket, $buffSize)
If @error <> 0 Then Return -1
If $recv == "" Then
Sleep(20)
Else
$buff &= $recv
EndIf
If TimerDiff($timer) > $timeout Then Return -1
Until StringInStr($buff, $string) > 0
EndIf
Return 0
EndFunc
Func _CleanOnExit()
If $socket <> -1 Then TCPCloseSocket($socket)
MsgBox(0,"","如果telnet返回不是-1,就关闭tcp连接")
TCPShutdown()
EndFunc
回复 9# 小熵
没看懂你的问题。。。
server不对,TCPConnect就会出错,会设置@error,Init函数就会返回-1啊
你为什么搞个错误的server和用户名呢?
还有,关于$buff的定义重复了,在文件开头定义,保留上面一个即可。 搞个错误的就是为了测试会不会@error返回-1
我也被搞的非常糊涂了,表示作为一个非编程的人士,autoit的代码还是很难懂
页:
[1]