一、概要
由于偶尔需要重启zimbra服务,出现故障时运维人员可能不在电脑旁,故想要如何来使用手机便捷得去重启服务器上的服务。服务器出于安全考虑,采用跳板机的方式ssh登录,再进行重启服务操作
二、难点
zimbra服务器这里称为A,跳板机称为B,运维人员终端称为C
- A只允许B进行ssh连接,也就是如果C要操作A,只能先连接上B,再从B使用ssh连接A,进行对A的操作
- 如何远程操作A服务器
- socket服务端启用端口监听后,由于硬件防火墙限制,监听端口外网无法访问
- socket多用户连接导致阻塞
- 多用户在操作的时候,如果同一条命令没有执行完,只允许一个用户正常执行
三、python sshtunnel 模块
为了解决跳板机的问题,以及监听端口外网无法访问的问题,这里我想到了使用ssh的隧道来进行连接(题外话,ssh隧道很强大,有兴趣的同学可以去谷歌学习了解下),那么python如何实现ssh隧道呢?这里就用到了sshtunnel,附上官方使用说明:https://github.com/pahaz/sshtunnel,然后下面先把代码贴出来:
#!/usr/bin/env python
# coding:utf-8
# Build by Zengfl
from sshtunnel import SSHTunnelForwarder
def connserver(host, port):
server = SSHTunnelForwarder(
ssh_address=('serverIP',serverport),
ssh_username='sshname',
ssh_password='sshpasswd',
local_bind_address=('127.0.0.1',55005),
remote_bind_address=('172.25.4.21',55005)
) #创建ssh隧道
try:
server.start() #ssh隧道连接
except:
print "[SSH CONNECT ERROR]"
exit(1)
- ssh_address: 我这里写的跳板机的IP地址和端口
- ssh_username:连接跳板机的ssh用户名
- ssh_password: 连接跳板机的ssh密码
- local_bind_address:ssh连上跳板机后绑定本地的哪个ip和端口,我这里绑定的是我本机的55005端口(端口数字随便设,只要不和本机已用端口冲突即可)
- remote_bind_address:将上条绑定的端口和远程服务器的端口进行绑定映射,这里我绑定的就是zimbra服务器的55005端口
以上代码便创建了ssh隧道,并将远端zimbra服务器上的55005端口映射到我本机的55005端口,之后我访问本机的55005端口即是访问zimbra服务器的55005端口,完美绕过跳板机和防火墙的限制(思考:如果是mysql服务器如何来进行隧道连接)
四、python socket网络编程
Ⅰ.方案选择
在解决了远程连接到跳板机后端的服务器之后,就要思考如何来对后端的服务器进行操作,当时我想到了两个方案:
- Web页来进行操作
- 通过socket来进行操作
由于考虑到使用web来操作的话,有点重,并且开发周期会稍长一点(可能是我比较菜,大佬应该还是挺快的),所以我这里选择了socket来进行操作,做个轻量级的远程控制
Ⅱ.socket编程思路
TCP服务端: (UDP这里不做介绍,由于本文主要概述一下 Python Socket 来解决服务器上服务的操作,因此不会对相关函数参数、返回值进行详细介绍,需要了解的可以查看相关手册)
- 创建套接字,绑定套接字到本地IP与端口
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind()
- 开始监听连接
s.listen()
- 进入循环,不断接受客户端的连接请求,并将连接的请求赋值给变量
s.accept()
- 接收/发送数据
s.recv()
s.sendall()
- 传输完毕后,关闭套接字
s.close()
TCP客户端:
- 打开 socket
socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect()
- 连接后发送数据和接收数据
s.sendall()
s.recv()
- 传输完毕后,关闭套接字
s.close()
Ⅲ. 创建socket客户端和服务端连接
按照以上思路如下编写
服务端:
#!/usr/bin/env python
# coding:utf-8
# Build by Zengfl
import socket
import sys
import time
# 创建socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
# 绑定socket的ip和端口
try:
s.bind(("", 55005))
except socket.error , msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
# 监听端口(用来控制连接的个数。如果设为 5,那么有 5 个连接正在等待处理,此时第 6 个请求过来时将会被拒绝)
s.listen(5)
print "[+] Server is running on port: 55005 at %s" % (time.strftime("%Y%m%d %H:%M:%S", time.localtime()))
# 接收连接
mainsocket, mainhost = s.accept()
print "[+] Connect success -> %s at %s" % (str(mainhost), time.strftime("%Y%m%d %H:%M:%S", time.localtime()))
# 接收消息
data = mainsocket.recv(1024)
if data:
print "[+] Receive:%s" % data
# 发送给客户端消息接收成功的信息
mainsocket.sendall("[Server]success")
mainsocket.close()
s.close()
客户端:
#!/usr/bin/env python
# coding:utf-8
# Build by Zengfl
import time
import socket
# 创建socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, 55005)) #host配置服务端的ip
# 终端输入并发送到服务端
print "\n[*] Please input command:"
data = raw_input()
s.sendall(data)
# 接收服务端的返回结果
recvdata = s.recv(1024)
print "[+] Send %s:55005 -> %s" % (host, data)
if recvdata:
print "[+] Receive :%s" % recvdata
运行结果:
服务端:
[root@iZwz9esy3n96ermeee5jzkZ ~]# python server.py
Socket created
[+] Server is running on port 55005: at 20171228 13:33:50
[+] Connect success -> ('183.15.179.197', 52653) at 20171228 13:34:23
[+] Receive:hello world
客户端:
C:\Users\Zengfl\Desktop>python client.py
[*] Please input command:
hello world
[+] Send xxx.xxx.xx.xxx:55005 -> hello world
[+] Receive :[Server]success
总结:
如上则完成了一次简单的会话通讯,但是还是没有达到我所期望的目的。我们期望的是:
- 服务端能够无限制接收客户端过来的消息,并不是完成一次会话后就断开连接
- 服务端接收到客户端的固定指令(exit,quit,close)才断开连接
- 客户端也要同样的无限制得可以向服务端发送消息
- 客户端发送固定执行(exit,quit,close)自己中断连接
Ⅳ. 优化(1)
针对上方总结出的需求,对代码进行优化,需要将服务端一直接受请求,最简单的办法就是将服务端接收消息放到一个循环中无限执行,这样就能一直接收,客户端同理
至于如何中断连接,对数接收到的数据进行判断,如果为exit,quit,close,则关闭连接,并且推出循环。
优化后的代码如下:
服务端(这里使用函数来封装,便于使用)
#!/usr/bin/env python
# coding:utf-8
# Build by Zengfl
import socket
import sys
import time
import threading
def recvdata(port):
close_list=["close session","exit","quit","close"] # 断开连接指令列表
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', port))
s.listen(5)
print "[+] Server is running on port:%s at %s" % (str(port), time.strftime("%Y%m%d %H:%M:%S", time.localtime()))
mainsocket, mainhost = s.accept()
print "[+] Connect success -> %s at %s" % (str(mainhost), time.strftime("%Y%m%d %H:%M:%S", time.localtime()))
if mainhost:
# 增加收发消息的循环
while True:
data = mainsocket.recv(1024)
if data:
print "[+] Receive:%s" % data
mainsocket.sendall("[Server]success")
#判断是否是断开连接的指令
if data in close_list:
mainsocket.close()
print "[+] Quit success"
break
if __name__ == "__main__":
connPort = 55005
onethreads = threading.Thread(target=recvdata, args=(connPort,))
onethreads.start()
客户端
#!/usr/bin/env python
# coding:utf-8
# Build by Zengfl
import time
import socket
def connserver(host, port):
close_list=["close session","exit","quit","close"] #监听输入状态,如果为这些状态则断开连接
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
while True:
print "\n[*] Please input command:"
data = raw_input()
if not data:
continue
s.sendall(data)
recvdata = s.recv(1024)
time.sleep(0)
if recvdata:
print "[+] Receive :%s" % recvdata
if data in close_list:
print "[+] Close sucess"
s.close()
break
if __name__ == "__main__":
server_list = ["xxx.xxx.xxx.xxx"]
connPort = 55005
if server_list != []:
for host in server_list:
connserver(host, connPort)
运行结果:
服务端:
[root@iZwz9esy3n96ermeee5jzkZ ~]# python server.py
[+] Server is running on port:55005 at 20171228 14:55:10
[+] Connect success -> ('183.15.179.197', 53661) at 20171228 14:55:54
[+] Receive:hello world
[+] Receive:my name is kard
[+] Receive:bye bye
[+] Receive:exit
[+] Quit success
[root@iZwz9esy3n96ermeee5jzkZ ~]#
客户端:
C:\Users\Zengfl\Desktop>python client.py
[*] Please input command:
hello world
[+] Receive :[Server]success
[*] Please input command:
my name is kard
[+] Receive :[Server]success
[*] Please input command:
bye bye
[+] Receive :[Server]success
[*] Please input command:
exit
[+] Receive :[Server]success
[+] Close sucess
总结:
从上述代码来看,我们已经解决了之前遇到的问题,实现了客户端可以多次发送消息,但是又有新的问题:
- 服务端在收到客户端退出请求以后,服务端也退出了监听,我想要的是服务端一直处于监听状态,只要有客户端连接进来,就能够正常收发消息
Ⅴ. 优化(2)
针对此问题,我们只需要修改服务端,将监听会话连接也加个循环即可
服务端
#!/usr/bin/env python
# coding:utf-8
# Build by Zengfl
import socket
import sys
import time
import threading
def recvdata(port):
close_list=["close session","exit","quit","close"] # 断开连接指令列表
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', port))
s.listen(5)
print "[+] Server is running on port:%s at %s" % (str(port), time.strftime("%Y%m%d %H:%M:%S", time.localtime()))
# 增加连接建立的循环
while True:
mainsocket, mainhost = s.accept()
print "[+] Connect success -> %s at %s" % (str(mainhost), time.strftime("%Y%m%d %H:%M:%S", time.localtime()))
if mainhost:
# 增加收发消息的循环
while True:
data = mainsocket.recv(1024)
if data:
print "[+] Receive:%s" % data
mainsocket.sendall("[Server]success")
#判断是否是断开连接的指令
if data in close_list:
mainsocket.close()
print "[+] Quit success"
break
if __name__ == "__main__":
connPort = 55005
onethreads = threading.Thread(target=recvdata, args=(connPort,))
onethreads.start()
运行结果:
服务端
[root@iZwz9esy3n96ermeee5jzkZ ~]# python server.py
[+] Server is running on port:55005 at 20171228 16:00:28
[+] Connect success -> ('183.15.179.197', 54658) at 20171228 16:01:11
[+] Receive:hello wordl
[+] Receive:ni hao
[+] Receive:bye bye
[+] Receive:exit
[+] Quit success
[+] Connect success -> ('183.15.179.197', 54663) at 20171228 16:01:34
[+] Receive:nihao
[+] Receive:bye
[+] Receive:close
[+] Quit success
客户端
C:\Users\Zengfl\Desktop>python client.py
[*] Please input command:
hello wordl
[+] Receive :[Server]success
[*] Please input command:
ni hao
[+] Receive :[Server]success
[*] Please input command:
bye bye
[+] Receive :[Server]success
[*] Please input command:
exit
[+] Receive :[Server]success
[+] Close sucess
----------------------------------------------------------------------------------------------------------------
C:\Users\Zengfl\Desktop>python client.py
[*] Please input command:
nihao
[+] Receive :[Server]success
[*] Please input command:
bye
[+] Receive :[Server]success
[*] Please input command:
close
[+] Receive :[Server]success
[+] Close sucess
总结:
以上方式修改了之后,服务端能够一直监听客户端,并响应消息,客户端退出重连都可以正常使用。but!新的问题和需求来了:
- 当一个客户端连接上了之后,socket处于消息阻塞,故新的客户端连接上去,服务端无法正常响应,并且新客户端会处于卡死状态(具体原因是什么我还没有去研究,忘大佬解答)
- 当客户端输入Ctrl+c 退出后,服务端没有接收到退出信息,故没有中断客户端连接,导致服务端连接被占用
- 并且我们需要判断客户端的消息,然后进行服务器上的操作
- 已经在操作系统命令,不允许重复执行
Ⅵ. 优化(3)
对于消息阻塞,我这里想到了用多线程来解决此问题
对于客户端输入Ctrl+c 我采用监控KeyboardInterrupt异常来进行判断,如果出现此异常则向服务端发送中断消息
然后客户端消息判断,则在服务端加一个判断的函数,监听cmd.run开头的信息,如果客户端以cmd.run来发送消息,服务端则执行cmd.run 后面的语句。
已经在执行的命令,通过ps在服务上查看进程,判断命令是否正在执行
代码如下:
服务端 (注释解释得挺详细了)
#!/usr/bin/env python
# coding:utf-8
# By Zengfl
import time
import socket
import threading
import traceback
import subprocess
from thread import *
# 处理收到消息的方法,判断消息是否为cmd.run 开头
def parsecmd(strings):
midsplit = str(strings).split(" ")
# 判断消息是否大于2个传参并且为cmd.run开头
if len(midsplit) >= 2 and midsplit[0] == "cmd.run":
# 统计传入的命令在服务器上是否有进程在运行,再进行判断
res=subprocess.Popen("ps -ef|grep \""+strings[8:]+"\"|grep -v grep|wc -l",stdout=subprocess.PIPE,shell=True)
pronum=int(res.stdout.read())
if pronum < 1:
try:
# 正常执行消息传进来的参数
command = subprocess.Popen(strings[8:], shell=True)
command.communicate()
print "传参:%s,执行成功...请稍等"%strings
except Exception, e:
# 传参执行失败
print "传参:%s,执行失败!!!"%strings
print e.message
traceback.print_exc()
else:
# 如果消息中传的参数,服务器上有进行在运行,则不执行
print "传参:%s,正在执行。"%strings
else:
# 如果消息不以cmd.run 开头并且少于2个传参,则不执行
print "收到传参:%s,不予执行!"%strings
# 客户端消息收发的方法
def clientthread(mainsocket):
close_list=["close session","exit","quit","close"]
while True:
data = mainsocket.recv(1024)
if data:
mainsocket.sendall("[Server] success")
# 将收到的消息,传到消息处理的方法中,进行消息处理
parsecmd(data)
if data in close_list:
print "[+] Client quit success"
break
mainsocket.close()
# 创建socket,并建立连接的方法
def recvdata(port):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 这条是我在网上看到粘包的问题,加上的
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', port))
s.listen(5)
print "[-] Server is running on port:%s" % str(port)
while True:
mainsocket, mainhost = s.accept()
print "[+] Connect success -> %s" % str(mainhost)
# 判断连接是否成功,如果连接成功,将此连接的会话创建到一个线程中
if mainhost:
# 创建线程,线程中调用客户端收发消息的方法
start_new_thread(clientthread ,(mainsocket,))
if __name__ == "__main__":
connPort = 55005
onethreads = threading.Thread(target=recvdata, args=(connPort,))
onethreads.start()
客户端
#!/usr/bin/env python
# coding:utf-8
# Build by Zengfl
#
import time
import socket
def connserver(host, port):
close_list=["close session","exit","quit","close"] # 监听输入状态,如果为这些状态则断开连接
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
while True:
try:
print "\n[*] Please input command:"
data = raw_input()
if not data:
continue
s.sendall(data)
recvdata = s.recv(1024)
time.sleep(0)
if recvdata:
print "[+] Receive :%s" % recvdata
if data in close_list:
print "[+] Close sucess"
s.close()
break
except KeyboardInterrupt: #监听键盘输出Ctrl + c,并发送中断消息以及中断连接
s.sendall("close session")
recvdata = s.recv(1024)
if recvdata:
print "[+] Close sucess"
s.close()
break
if __name__ == "__main__":
server_list = ["xxx.xxx.xxx.xxx"]
connPort = 55005
if server_list != []:
for host in server_list:
connserver(host, connPort)
运行结果:
客户端1
C:\Users\Zengfl\Desktop>python test.py
[*] Please input command:
hello
[+] Receive :[Server] success
[*] Please input command:
world
[+] Receive :[Server] success
[*] Please input command:
wo shi 1
[+] Receive :[Server] success
[*] Please input command:
wo zai xian
[+] Receive :[Server] success
[*] Please input command:
bye bye
[+] Receive :[Server] success
[*] Please input command:
exit
[+] Receive :[Server] success
[+] Close sucess
C:\Users\Zengfl\Desktop>
客户端2
C:\Users\Zengfl\Desktop>python test.py
[*] Please input command:
hello
[+] Receive :[Server] success
[*] Please input command:
wo shi 2
[+] Receive :[Server] success
[*] Please input command:
1 zai xian ma
[+] Receive :[Server] success
[*] Please input command:
1 zou le
[+] Receive :[Server] success
[*] Please input command:
wo ye zou le
[+] Receive :[Server] success
[*] Please input command:
exit
[+] Receive :[Server] success
[+] Close sucess
C:\Users\Zengfl\Desktop>
客户端3
C:\Users\Zengfl\Desktop>python test.py
[*] Please input command:
cmd.run echo 111 > /tmp/hello
[+] Receive :[Server] success
[*] Please input command:
byebye
[+] Receive :[Server] success
[*] Please input command:
close
[+] Receive :[Server] success
[*] Please input command:
close session
[+] Receive :[Server] success
[+] Close sucess
C:\Users\Zengfl\Desktop>
服务端
[root@iZwz9esy3n96ermeee5jzkZ ~]# python server.py
[-] Server is running on port:55005
[+] Connect success -> ('183.15.179.197', 55884)
收到传参:hello,不予执行!
收到传参:world,不予执行!
收到传参:wo shi 1,不予执行!
[+] Connect success -> ('183.15.179.197', 55890)
收到传参:hello,不予执行!
收到传参:wo shi 2,不予执行!
收到传参: 1 zai xian ma,不予执行!
收到传参:wo zai xian,不予执行!
收到传参:bye bye,不予执行!
收到传参:exit,不予执行!
[+] Client quit success
收到传参:1 zou le,不予执行!
收到传参:wo ye zou le ,不予执行!
收到传参:exit,不予执行!
[+] Client quit success
[+] Connect success -> ('183.15.179.197', 57579)
传参:cmd.run echo 111 > /tmp/hello,执行成功...请稍等
收到传参:byebye,不予执行!
收到传参:close ,不予执行!
收到传参:close session,不予执行!
[+] Client quit success
在服务端查看 /tmp/hello 文件:
[root@iZwz9esy3n96ermeee5jzkZ ~]# cat /tmp/hello
111
[root@iZwz9esy3n96ermeee5jzkZ ~]#
总结:
综上,所有的需求都完成了。解决了下面几个功能:
- 服务端能够无限制接收客户端过来的消息,并且支持多个终端同时连接,同时进行会话
- 服务端接收到客户端的固定指令(exit,quit,close)断开连接
- 服务端可执行客户端发送过来的执行命令
- 服务端不允许执行正在运行的命令
- 客户端也要同样的无限制得可以向服务端发送消息
- 客户端发送固定执行(exit,quit,close)自己中断连接,客户端执行Ctrl+c也能中断连接
- s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 这个解决粘包问题:参考文档
五、结合ssh隧道,实现跨跳板机进行服务端会话
跳板机的问题解决了
服务端远程执行远程指令也解决了
现在就使用这两个功能实现我们最初的目的,并将之前print的输出记录到日志,直接贴代码吧:
服务端
#!/usr/bin/env python
# coding:utf-8
# By Zengfl
import time,os,logging
import socket
import threading
import traceback
import subprocess
from thread import *
#日期模块
def unix_te(day=0):
return time.strftime(
'%Y-%m-%d',
time.localtime(time.time()-86400*day)
)
#定义日志配置
if not os.path.exists('/home/work/script/logs'): os.system('mkdir -p /home/work/script/logs')
logging.basicConfig(filename = '/home/work/script/logs/%s.log' % unix_te(), level = logging.DEBUG, filemode = 'a', format = '%(asctime)s - %(levelname)s: %(message)s')
def parsecmd(strings):
midsplit = str(strings).split(" ")
if len(midsplit) >= 2 and midsplit[0] == "cmd.run":
res=subprocess.Popen("ps -ef|grep \""+strings[8:]+"\"|grep -v grep|wc -l",stdout=subprocess.PIPE,shell=True)
pronum=int(res.stdout.read())
if pronum < 1:
try:
command = subprocess.Popen(strings[8:], shell=True)
command.communicate()
logging.info("传参:%s,执行成功...请稍等"%strings)
except Exception, e:
logging.error("传参:%s,执行失败!!!"%strings)
print e.message
traceback.print_exc()
else:
logging.warning("传参:%s,正在执行。"%strings)
else:
logging.info("收到传参:%s,不予执行!"%strings)
def clientthread(mainsocket):
close_list=["close session","exit","quit","close"]
while True:
data = mainsocket.recv(1024)
if data:
mainsocket.sendall("[Server] success")
parsecmd(data)
if data in close_list:
#mainsocket.close()
logging.info("[+] Client quit success")
break
mainsocket.close()
def recvdata(port):
#close_list=["close session","exit","quit","close"]
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', port))
s.listen(5)
logging.info("[-] Server is running on port:%s" % str(port))
while True:
mainsocket, mainhost = s.accept()
logging.info("[+] Connect success -> %s" % str(mainhost))
if mainhost:
start_new_thread(clientthread ,(mainsocket,))
if __name__ == "__main__":
connPort = 55005
onethreads = threading.Thread(target=recvdata, args=(connPort,))
onethreads.start()
客户端
#!/usr/bin/env python
# coding:utf-8
# Build by Zengfl
import time
import socket
from sshtunnel import SSHTunnelForwarder
def connserver(host, port):
server = SSHTunnelForwarder(
ssh_address=('xx.xx.xx.xx',xxx),
ssh_username='xxx',
ssh_password='xxxx',
local_bind_address=('127.0.0.1',55005),
remote_bind_address=('192.168.1.21',55005)
) #创建ssh隧道
try:
server.start() #ssh隧道连接
except:
print "[SSH CONNECT ERROR]"
exit(1)
close_list=["close session","exit","quit","close"] #监听输入状态,如果为这些状态则断开连接
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
while True:
try:
print "\n[*] Please input command:"
data = raw_input()
if not data:
continue
s.sendall(data)
recvdata = s.recv(1024)
time.sleep(0)
if recvdata:
print "[+] Receive :%s" % recvdata
if data in close_list:
print "[+] Close sucess"
s.close()
break
except KeyboardInterrupt: #监听键盘输出Ctrl + c,并中断连接
s.sendall("close session")
recvdata = s.recv(1024)
if recvdata:
print "[+] Close sucess"
s.close()
break
server.stop() #关闭ssh隧道
if __name__ == "__main__":
server_list = ["127.0.0.1"] # 这里很重要,因为我ssh做隧道的时候监听的就是本机的55005端口
connPort = 55005
if server_list != []:
for host in server_list:
connserver(host, connPort)
重启zimbra脚本
#!/usr/bin/env python
# coding:utf-8
# Build by Zengfl
import time
import socket
from sshtunnel import SSHTunnelForwarder
def connserver(host, port):
server = SSHTunnelForwarder(
ssh_address=('xxx.xxx.xxx.xxx',xxx),
ssh_username='xxx',
ssh_password='xxx',
local_bind_address=('127.0.0.1',55005),
remote_bind_address=('192.168.1.21',55005)
) #创建ssh隧道
try:
server.start() #ssh隧道连接
except:
print "[SSH CONNECT ERROR]"
exit(1)
close_list=["close session","exit","quit","close"] #监听输入状态,如果为这些状态则断开连接
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
data = "cmd.run /etc/init.d/zimbra restart"
s.sendall(data)
recvdata = s.recv(1024)
if recvdata:
print "[+] Receive :%s" % recvdata
print u"操作成功,请等待5分钟后检测邮件收发是否正常"
else:
print "操作失败"
s.sendall("close session")
recvdata = s.recv(1024)
s.close()
server.stop() #关闭ssh隧道
if __name__ == "__main__":
server_list = ["127.0.0.1"]
connPort = 55005
if server_list != []:
for host in server_list:
connserver(host, connPort)
测试这里就不演示了,我这里已经在正常使用了,同学们可以参考此代码自行进行尝试
六、总结:
目前为止,已经解决了我所期望的需求,最后再将程序打个exe包就行了。具体如何打包,使用pyinstaller这个工具,怎么使用不是本文的重点
代码有写得不好的地方忘大佬们多多包涵并指出缺点,定改正
本文主要讲述的是一个解决问题的思路,一步步将我解决问题的流程和思路捋了出来,说实话写这篇文章比我完成这份代码花的时间长得多。
当碰到需求不要急于去动手做,先想好这个需求需要面临些什么问题,然后再化整为零,把需求细分成小的功能点,逐一解决,最后将各个功能点结合起来,然后大功告成,撒花
网友评论