1.cmd命令 利用socket
socket服务端
1 import socket 2 import subprocess 3 s = socket.socket() 4 s.bind(("127.0.0.1",8000)) 5 s.listen(3) 6 print("waiting...") 7 while 1: 8 conn,addr = s.accept() 9 print(conn) 10 while 1: 11 try: 12 a = conn.recv(1024) 13 except Exception: 14 break 15 if not a: 16 break 17 print(">>>",str(a,"utf8")) 18 obj = subprocess.Popen(a.decode("utf8"),shell=True,stdout=subprocess.PIPE) 19 result = obj.stdout.read() 20 print('ooooo',type(result)) 21 result_len = bytes(str(len(result)),"utf8") # result是unicode编码下的十六进制 所以先转换成字符串(Unicode) 在转换成bytes 22 conn.sendall(result_len) # 两个send在一起容易发生粘包 特别是第一个数据特别小的时候 23 conn.sendall(result) # 所以在send之间在来个一收一发 24 s.close()
client客户端
1 import socket 2 s = socket.socket() 3 ss = ("127.0.0.1",8000) 4 s.connect(ss) 5 while 1: 6 inp = input(">>>") 7 if inp =="q": 8 break 9 s.send(bytes(inp,"utf8")) # send 传送智能是bytes类型 10 result_len = int(str(s.recv(1024),"utf8")) # 二进制的不能直接转换成整形!!! 11 print(result_len) 12 data = bytes() 13 while len(data)!=result_len: # 大文件传输过程中 不能一次传完 造成延迟 所以要先 14 data += s.recv(1024) # 传输文件的大小 根据大小判断文件传输 15 print(str(data,"gbk")) 16 s.close()
上述的代码实现了client端发送cmd指令到serve端进行执行后返回给client端结果的一个过程。
attention:一发一收
socket创建
s = socket.socket()这样就创建了一个socket对象。在serve端和client端分别需要创建一个。括号中仍有4个默认函数:
family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None
其中family是IPV4 的默认值,type是TCP的默认值。
设置值
创建好socket之后,serve端需要设置(4,5行)
1 bind绑定IP和端口。
2 listening值是最多等待。
3 接受client协议和地址 即 第八行
4 注意这里的conn就是client端的.socket 所以在接收的时候为conn.receive
client端只用设置连接的address和端口。
小细节
1.serve端的try是防止client端直接结束造成接收报错。
2.若接收的a为空表示client端主动断开了socket连接(本身发送不能发送空)。
关于subprocess
obj = subprocess.Popen(a.decode("utf8"),shell=True,stdout=subprocess.PIPE)
result = obj.stdout.read()
这两句话实现了cmd在子程序中运行后返回结果到result。
注意这里的result是gbk编码下的bytes类型。
关于这其中杂乱的编码
Python3中有两种格式:
str:str>>bytes 称为编码(encode)方法有1.re=bytes(“ccc”,“utf8”)2.re=“ccc”.encode(“utf8”)py3中str都是Unicode编码。兼容utf8,三字节表示中文。
bytes:bytes>>str称为解码(decode)方法有1.re = str(“ccc”,“utf8”)2.re=“ccc”.decode(“utf8”)bytes类型有相对应的编码协议。即什么样的编码形式 (如utf8)就仍用什么样的解码。
Python2中也有两种:
str:即原来的3中的bytes
Unicode:即str u“你好” 表示内容用的Unicode编码。
pyhton3中页面用到utf8,2中用的阿斯克码。
大文件传输问题解决
发送端的sendall必将数据都发送过去,但是接收的时候一次最多接收设置值1024个字节。(received值最大8K)所以造成接收时显示缓慢。(接收第二条时仍旧显示第 一条)
解决办法是:多次循环接收直到data大小等于文件大小。while len(data)!=result_len:不相等就继续接收。
2.socketserve
serve端
1 import socketserver 2 class Myserve(socketserver.BaseRequestHandler): 3 def handle(self): 4 print("active") 5 while 1: 6 conn = self.request 7 print(self.client_address) 8 while 1: 9 a = conn.recv(1024) 10 print(">>>", str(a, "utf8")) 11 if not a: 12 break 13 inp = input(">>>") 14 conn.send(bytes(inp, "utf8")) 15 conn.close() 16 mine = socketserver.ThreadingTCPServer(("127.0.0.1",8000),Myserve) 17 mine.serve_forever()
上述通过调用socketserver实现了多个client和一个server进行通信的功能。
实现过程:
创建一个自己命名的server类myserver
只在此类中创建一个方法:handle名字不能变,逻辑按照功能设计
创建socketserver对象,调用ThreadingTCPServer方法传入address元组,和server。
serverforever()激活这个并发的server。