一.基于tcp协议的通信套接字(循环链接)
服务端代码: from socket import * server = socket(AF_INET, SOCK_STREAM) server.bind(("127.0.0.1", 8081)) server.listen(5) # 链接循环 while True: conn, addr = server.accept() # 通信循环 while True: try: #try 与 except 的作用是:当客户端单方面的断开连接是,接收异常,并断开连接,结束此次服务,但服务器的服务不会断开 data = conn.recv(1024) print(data.decode("utf-8")) msg = input(">>>:").strip() conn.send(msg.encode("utf-8")) except ConnectionResetError: break conn.close() server.close() 客户端代码: from socket import * client = socket(AF_INET,SOCK_STREAM) client.connect(("127.0.0.1",8081)) #通信循环 while True: data1= input(">>>:").strip() if len(data1)==0:continue client.send(data1.encode("utf-8")) data=client.recv(1024) print(data.decode("utf-8")) client.close()
二.模拟ssh实现远程执行命令(会出现粘包问题)
服务端代码: from socket import * import subprocess server = socket(AF_INET, SOCK_STREAM) server.bind(("127.0.0.1", 8081)) server.listen(5) # 连接循环 while True: conn, addr = server.accept() # 通信循环 while True: try: # 接收信息: cmd = conn.recv(1024) obj = subprocess.Popen(cmd.decode("utf-8"), shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE ) stdout = obj.stdout.read() stderr = obj.stderr.read() # 发送消息 conn.send(stderr + stdout) except ConnectionResetError: break conn.close() server.close() 客户端代码: from socket import * client = socket(AF_INET, SOCK_STREAM) client.connect(("127.0.0.1", 8081)) # 通信循环 while True: # 发送消息 cmd = input(">>>:").strip() if len(cmd) == 0: continue client.send(cmd.encode("utf-8")) # 接受信息 data1=client.recv(1024) print(data1.decode("gbk")) client.close()
三.模块struct
import struct data=struct.pack("i",12312) print(data,len(data)) #会将一定长度的整型,变成长度固定的字节 data1=struct.unpack("i",data) print(data1[0]) #粘包问题:是tcp协议流式传输数据的方式导致的 #解决粘包问题:接收端能够精确的收干净每个数据包,没有残留
四.二.模拟ssh实现远程执行命令(解决现粘包问题的初级方法)
服务端代码: from socket import * import subprocess import struct server= socket(AF_INET,SOCK_STREAM) server.bind(("127.0.0.1",8081)) server.listen(5) #链接循环 while True: conn,addr = server.accept() #通信循环 while True: try: #接收信息 cmd = conn.recv(1024) obj=subprocess.Popen(cmd.decode("utf-8"), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) stdout=obj.stdout.read() stderr=obj.stderr.read() header= struct.pack("i",len(stdout)+len(stderr)) #先发送报头长度:(统一为四个字节) conn.send(header) #再发送真实数据: conn.send(stderr+stdout) except ConnectionResetError: break conn.close() server.close() 客户端代码: from socket import * import struct client = socket(AF_INET,SOCK_STREAM) client.connect(("127.0.0.1",8081)) #通信连接 while True: #发送命令 cmd = input(">>>:").strip() if len(cmd)==0:continue client.send(cmd.encode("utf-8")) #接收信息: # 1. 先接收报头的信息 header=client.recv(4) tottal_size=struct.unpack("i",header)[0] #为真实数据的长度 # 2. 再接收真正的数据 cmd_res=b"" size_cmd=0 while size_cmd<tottal_size: data=client.recv(1024) size_cmd += len(data) cmd_res += data print(cmd_res.decode('gbk')) client.close()
五.模拟ssh实现远程执行命令(解决现粘包问题的终级方法)
服务端代码: from socket import * import struct import json import subprocess server=socket(AF_INET,SOCK_STREAM) server.bind(("127.0.0.1",8081)) server.listen(5) #链接循环 while True: conn,addr=server.accept() #通信循环 while True: try: cmd = server.recv(1024) obj=subprocess.Popen(cmd.decode("utf-8"),shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) stdout=obj.stdout.read() stderr=obj.stderr.read() # 1 制作报头: header_dic ={ "filename":"a.txt", "md5":"erhwer", "header_size":len(stdout)+len(stderr) } # 对报头序列化 header_json=json.dumps(header_dic) #对应写 #将序列化好的报头转为字节 header_bytes=header_json.encode("utf-8") # 2 先发送4个bytes(包含报头的长度) conn.send(struct.pack("i",len(header_bytes))) # 3 再发送报头 conn.send(header_bytes) # 4 发送真实的数据 conn.send(stderr+stdout) except ConnectionResetError: break conn.close() server.close() 客户端代码: from socket import * import struct import json client = socket(AF_INET,SOCK_STREAM) client.connect(("127.0.0.1",8081)) #通信循环 while True: #发送命令 cmd = input(">>>:").strip() if len(cmd)==0:continue client.send(cmd.encode("utf-8")) #接收信息 # 1 先收四个bytes 再解出报头长度 header_size=struct.unpack("i",client.recv(4))[0] # 2 再接收报头,拿到header_dic header_bytes=client.recv(header_size) header_json=header_bytes.decode("utf-8") header_dic=json.loads(header_json) tottal_size=header_dic["header_size"] #接收真实的数据 cmd_res= b"" res_size=0 while res_size < tottal_size: data=client.recv(1024) cmd_res += data res_size += len(data) print(cmd_res.decode("gbk")) client.close()