TCP 套叠字
一、 TCP 协议
# ------------TCP套叠字--------------------
server 端
import socket,time ip_port=('localhost',51590) bank_log=5 buffer_size=1024 tcp_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # sk.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) # 重用ip和端口解决time——wait状态(address already in use) tcp_server.bind(ip_port) tcp_server.listen(bank_log) print("waiting for connet...") while True: print("server working...") conn,addr = tcp_server.accept() print('server===>') print("双向链接是",conn) print("客户端地址",addr) while True: try: data=conn.recv(buffer_size) print("clent send message is :",data.decode("utf-8")) time.sleep(2) conn.sendall(data.upper()) except Exception : print(Exception) break conn.close() sk.close()
TCP 客户端
import socket,time ip_port=('localhost',1234) bank_log=5 buffer_size=1024 tcp_clent = socket.socket(socket.AF_INET,socket.SOCK_STREAM) tcp_clent.connect(ip_port) while True: msg = input("请输入字符串:>>>").strip() if not msg:continue tcp_clent.sendall(msg.encode("utf-8")) data = tcp_clent.recv(buffer_size) print("server send message is :",data.decode("utf8")) tcp_clent.close()
二、UDP 协议
'''tcp协议实现客户端输入的命令执行、服务端返回命令执行的结果'''
客户端:
'''TCP 协议实现:客户端发送命令’并接收服务端发送过来的消息''' from socket import * ip_port=('localhost',51590) bank_log=5 buffer_size=1024 tcp_clent = socket(AF_INET,SOCK_STREAM) tcp_clent.connect(ip_port) while True: cmd = input("请输入字符串:>>>").strip() if not cmd:continue if cmd=="quit":break tcp_clent.send(cmd.encode("utf-8")) res_cmd = tcp_clent.recv(buffer_size) print("命令执行的结果是:",res_cmd.decode("gbk")) # 默认打开文件的编码为unicode默认编码是“gbk” tcp_clent.close()
服务端(解决粘包):
'''TCP 协议实现:客户端发送命令’服务端接收命令并把命令执行后的结果发送给客户端、 从缓存区取数据时取的少了就出现粘包、下次取的还是上次烦的内容'''
'''tcp协议实现客户端输入的命令执行、将结果放到管道中、在管道中读取返回带客户端''' import subprocess from socket import * ip_port = ("localhost", 51590) buffer_size = 1024 back_log=5 tcp_server=socket(AF_INET,SOCK_STREAM) tcp_server.bind(ip_port) tcp_server.listen(back_log) while True: print("waiting for connenct....") conn,addr=tcp_server.accept() print("双向链接是", conn) print("客户端地址", addr) while True: try: cmd = conn.recv(buffer_size) if not cmd:break print("收到客户端发送的消息是:",cmd) res = subprocess.Popen(cmd.decode("utf-8"),shell=True, stderr=subprocess.PIPE, stdin=subprocess.PIPE, stdout=subprocess.PIPE) err=res.stderr.read() if err: cmd_res=err else: cmd_res=res.stdout.read() if not cmd_res: cmd_res="执行成功".encode("gbk") conn.send(cmd_res) except Exception: print(Exception) break conn.close()
三、UDP 协议粘包现象
服务端:
'''UDP协议实现:客户端发送命令’服务端接收命令并把命令执行后的结果发送给客户端''' import subprocess from socket import * ip_port = ("localhost", 51590) buffer_size = 1024 back_log=5 udp_server=socket(AF_INET,SOCK_DGRAM) udp_server.bind(ip_port) while True: print("wait for send message...") cmd,addr = udp_server.recvfrom(buffer_size) print("收到客户端发送的消息是:",cmd) res = subprocess.Popen(cmd.decode("utf-8"), shell=True, stderr=subprocess.PIPE, stdin=subprocess.PIPE, stdout=subprocess.PIPE) err = res.stderr.read() if err: cmd_res = err else: cmd_res = res.stdout.read() if not cmd_res: cmd_res = "执行成功".encode("gbk") udp_server.sendto(cmd_res,addr) udp_server.close()
客户端:
import socket,time ip_port=('localhost',51590) bank_log=5 buffer_size=1024 tcp_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # sk.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) # 重用ip和端口解决time——wait状态(address already in use) tcp_server.bind(ip_port) tcp_server.listen(bank_log) print("waiting for connet...") while True: print("server working...") conn,addr = tcp_server.accept() print('server===>') print("双向链接是",conn) print("客户端地址",addr) while True: try: data=conn.recv(buffer_size) print("clent send message is :",data.decode("utf-8")) time.sleep(2) conn.sendall(data.upper()) except Exception : print(Exception) break conn.close() sk.close()
四、TCP struct 模块解决粘包方法:
服务端:
'''struct 解决粘包现象''' '''tcp协议实现客户端输入的命令执行、服务端返回命令执行的结果''' import struct,json from socket import * import subprocess ip_port = ("localhost", 51590) buffer_size = 1024 back_log = 5 tcp_server=socket(AF_INET,SOCK_STREAM) tcp_server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #就是它,在bind前加 tcp_server.bind(ip_port) tcp_server.listen(back_log) while True: print("waiting for connect...") conn,addr=tcp_server.accept() while True: try: cmd=conn.recv(buffer_size) if not cmd:break print('cmd: %s' %cmd) res=subprocess.Popen(cmd.decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) err = res.stderr.read() # print(err.decode("utf-8")) if err: back_msg = err else: back_msg = res.stdout.read() if not back_msg: back_msg="命令执行成功,".encode("utf-8") headers={'data_size':len(back_msg)} head_json=json.dumps(headers) head_json_bytes=bytes(head_json,encoding='utf-8') conn.send(struct.pack('i',len(head_json_bytes))) #先发报头的长度 conn.send(head_json_bytes) #再发报头 conn.sendall(back_msg) #在发真实的内容 except Exception: print(Exception) conn.close()
客户端:
'''struct 解决粘包现象''' '''TCP 协议实现:客户端发送命令’并接收服务端发送过来的消息''' from socket import * import struct,json ip_port=('localhost',51590) buffer_size=1024 tcp_clent = socket(AF_INET,SOCK_STREAM) tcp_clent.connect_ex(ip_port) while True: msg = input("请输入字符串:>>>").strip() if not msg:continue if msg=="quit":break tcp_clent.send(msg.encode("utf-8")) try: heard = tcp_clent.recv(4) heard_json_len=struct.unpack("i",heard)[0] heard_json=json.loads(tcp_clent.recv(heard_json_len).decode("utf-8")) data_len=heard_json['data_size'] recv_size=0 recv_data=b'' while recv_size<data_len: recv_data+=tcp_clent.recv(buffer_size) recv_size+=len(recv_data) print("命令执行的结果是:",recv_data.decode("gbk")) # 默认打开文件的编码为unicode默认编码是“gbk” except Exception: print(Exception) tcp_clent.close()