客户端服务端通信简图
两种粘包现象
解决粘包现象
只有tcp通信存在粘包现象
udp会直接产生OSError异常
客户端
from socket import *
import struct
from functools import partial
ip_port = ('127.0.0.1',8080)
back_log =5
buffer_size = 1024
tcp_client = socket(AF_INET,SOCK_STREAM)
tcp_client.connect(ip_port)
while True:
cmd = input(">>:").strip()
if not cmd:continue
if cmd == 'quit':break
tcp_client.send(cmd.encode('utf8'))
#解决粘包
length_data = tcp_client.recv(4) #接受数据长度
length = struct.unpack('i',length_data)[0]
#开始接受数据
# recv_size = 0
# recv_msg = b''
# while recv_size<length:
# recv_msg += tcp_client.recv(buffer_size)
# recv_size = len(recv_msg)
#牛逼的代码--这里实现有些问题--学习这种牛逼的写法
recv_msg = ''.join(iter(partial(tcp_client.recv,buffer_size),b''))
print(recv_msg.decode('gbk'))
tcp_client.close()
服务端
from socket import *
import subprocess
import struct
ip_port = ('127.0.0.1',8080)
back_log =5
buffer_size = 1024
tcp_server = socket(AF_INET,SOCK_STREAM)
tcp_server.bind(ip_port)
tcp_server.listen(back_log)
while True:
conn,addr = tcp_server.accept()
print("新的客户端",addr)
while True:
# 接收到的是客户端发来的命令,服务端执行,并返回结果
try:
cmd = conn.recv(buffer_size).decode('utf8')
if not cmd:break
print("客户端命令:",cmd)
#执行命令
res = subprocess.Popen(cmd,shell=True,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
stderr=subprocess.PIPE)
err = res.stderr.read()
if err:
cmd_res = err
else:
cmd_res = res.stdout.read()
# 命令正常执行没有返回值得情况下,比如cd ..
if not cmd_res:
cmd_res = 'exec success'.encode('gbk')
#解决粘包
length = len(cmd_res)
data_length = struct.pack('i',length)
#下面两个send会黏到一起;在客户端解决:第一次接受数据长度;第二次开始接受数据
#定制报文头
conn.send(data_length)
#真实发送数据
conn.send(cmd_res)
except ConnectionResetError as e:
print(e)
break
conn.close()
tcp_server.close()
网友评论