比如说实现两个手机之间的通信,需要做的几部:
服务端:
1,买手机
2,插卡
3,开机
4,等电话链接
5,基于建立的链接,收发协议
6,挂电话
7,关机
import socket #买手机 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #插卡 phone.bind(('127.0.0.1',8080)) #开机 phone.listen(5) #等电话链接 print('server start...') conn,client_addr=phone.accept() #(tcp链接,client_addr) print('链接',conn) print(client_addr) #基于建立的链接,收发消息 client_data=conn.recv(1024) print('客户端的消息',client_data) conn.send(client_data.upper()) #挂电话链接 conn.close() #关机 phone.close()
客户端:
import socket phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) phone.connect(('127.0.0.1',8080)) phone.send('hello'.encode('utf-8')) server_data=phone.recv(1024) print('服务端回应的消息',server_data) phone.close()
加上通信循环与链接循环:
服务端:
1 import socket 2 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 3 phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加 4 phone.bind(('127.0.0.1',8080)) 5 phone.listen(5) 6 print('server start...') 7 conn,client_addr=phone.accept() 8 9 while True: #通讯循环 10 client_data=conn.recv(1024) 11 # print('has rev') 12 conn.send(client_data.upper()) 13 14 conn.close() 15 16 phone.close()
客户端:
1 import socket 2 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 3 phone.connect(('127.0.0.1',8080)) 4 5 while True: 6 msg=input('>>: ').strip() 7 if not msg:continue 8 phone.send(msg.encode('utf-8')) 9 # print('====>has send') 10 server_data=phone.recv(1024) 11 # print('====>has recv') 12 print(server_data.decode('utf-8')) 13 14 phone.close()
解决粘包现象:
服务端:
1 import socket 2 import struct 3 import subprocess 4 import json 5 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 6 phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加 7 phone.bind(('127.0.0.1',8080)) 8 phone.listen(5) 9 print('server start...') 10 while True: #链接循环 11 conn,client_addr=phone.accept() 12 print(conn,client_addr) 13 14 while True: #通讯循环 15 try: 16 cmd=conn.recv(1024) 17 if not cmd:break 18 19 #执行命令,拿到结果 20 res=subprocess.Popen(cmd.decode('utf-8'), 21 shell=True, 22 stdout=subprocess.PIPE, 23 stderr=subprocess.PIPE) 24 25 stdout=res.stdout.read() 26 stderr=res.stderr.read() 27 28 29 #制作报头 30 header_dic={'total_size':len(stdout)+len(stderr),'md5':None} 31 header_json=json.dumps(header_dic) 32 header_bytes=header_json.encode('utf-8') 33 34 35 #1 先发报头的长度(固定4个bytes) 36 conn.send(struct.pack('i',len(header_bytes))) 37 38 39 #2 先发报头 40 conn.send(header_bytes) 41 42 43 #3 再发真实的数据 44 conn.send(stdout) 45 conn.send(stderr) 46 47 except Exception: #针对windwos 48 break 49 conn.close() 50 51 phone.close()
客户端:
1 import socket 2 import struct 3 import json 4 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 5 phone.connect(('127.0.0.1',8080)) 6 7 while True: 8 cmd=input('>>: ').strip() 9 if not cmd:continue 10 #发命令 11 phone.send(cmd.encode('utf-8')) 12 13 14 #先收报头的长度 15 struct_res=phone.recv(4) 16 header_size=struct.unpack('i',struct_res)[0] 17 18 #再收报头 19 header_bytes=phone.recv(header_size) 20 head_json=header_bytes.decode('utf-8') 21 head_dic=json.loads(head_json) 22 23 total_size=head_dic['total_size'] 24 #再收命令的执行结果 25 recv_size=0 26 data=b'' 27 while recv_size < total_size: 28 recv_data=phone.recv(1024) 29 recv_size+=len(recv_data) 30 data+=recv_data 31 32 #打印结果 33 print(data.decode('gbk')) 34 35 phone.close()
实现并发的代码:
服务端:
1 import socketserver 2 class MyTcphandler(socketserver.BaseRequestHandler): 3 def handle(self): 4 while True: #通信循环 5 data=self.request.recv(1024) 6 self.request.send(data.upper()) 7 if __name__ == '__main__': 8 #取代链接循环 9 server=socketserver.ThreadingTCPServer(('127.0.0.1',8080),MyTcphandler) 10 server.serve_forever()
客户端:
import socket phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) phone.connect(('127.0.0.1',8080)) while True: msg=input('>>: ').strip() if not msg:continue phone.send(msg.encode('utf-8')) server_data=phone.recv(1024) print(server_data.decode('utf-8')) phone.close()