标签:解决办法 停止 模块 sock byte 套接字 服务器 err list
server服务端
import socket
server = socket.socket()
server.bind(('127.0.0.1', 9527)) # 把地址绑定到套接字
server.listen(5) # 监听连接,半连接池,控制访问量
print('server is running...')
conn, addr = server.accept() # 接收客户端连接
data = conn.recv(1024) # 接收客户端信息
print(data) # 打印客户端信息
conn.send(b'hello I am server...') # 向客户端发送信息
conn.close() # 关闭客户端套接字
server.close() # 关闭服务器套接字(可选)
client客户端
import socket
client = socket.socket() # 创建客户端套接字
client.connect(('127.0.0.1', 9527))# 尝试连接服务器
print('client is running...')
client.send(b'hello I am client...')
data = client.recv(1024) # 对话(发送/接收)
print(data)
client.close() # 关闭客户端套接字
黏包现象的出现有两个问题
server端
# 问题一
import socket
import subprocess # 终端
server = socket.socket()
server.bind(('127.0.0.1', 9527))
server.listen(5)
while True:
conn, addr = server.accept()
print(addr)
while True:
try:
# recv从内存中获取数据
cmd = conn.recv(10)
if len(cmd) == 0:continue
cmd = cmd.decode('utf8')
if cmd == 'q':break
# 调用subprocess连接终端,对终端进行操作,并获取操作后正确或错误的结果
obj = subprocess.Popen(
# cmd接收解码后的字符串
cmd, shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
# 结果交给result
result = obj.stdout.read() + obj.stderr.read()
print(len(result))
print(result.decode('gbk'))
conn.send(result)
except Exception as e:
print(e)
break
conn.close()
colient端
# 问题一
import socket
client = socket.socket()
client.connect(('127.0.0.1', 9527))
while True:
cmd = input('客户端>>>:')
client.send(cmd.encode('utf-8'))
data = client.recv(1024)
print(len(data))
print(data.decode('gbk'))
print(data.decode('gbk'))
print('*' * 100)
data = client.recv(1024)
print(data.decode('gbk'))
print('*' * 100)
data = client.recv(1024)
print(data.decode('gbk'))
print('*' * 100)
server端
# 问题二
import socket
server = socket.socket()
server.bind(('127.0.0.1', 9527))
server.listen(5)
conn, addr = server.accept()
data = conn.recv(10)
print(data)
data = conn.recv(10)
print(data)
data = conn.recv(10)
print(data)
client端
# 问题二
import socket
client = socket.socket()
client.connect(('127.0.0.1', 9527))
client.send(b'hello')
client.send(b'hello')
client.send(b'hello')
client.send(b'hello')
解决办法
问题的根源在于,接收端不知道发送端将要传送的字节流的长度,所以解决黏包的方法就是围绕如何让发送端在发送数据前,把自己将要发送的字节流总大小让接收端知晓,然后接收端来一个死循环接收完所有数据
我们可以借助一个模块struct,它可以把要发送的数据长度转换成固定长度的字节,这样客户端每次接收消息之前只要先接收这个固定长度字节的内容看看接下来接收的信息大小,那么最终接收的数据只要达到这个值就停止,就可以刚好不多不少的接收完整的数据
import struct
obj = struct.pack('i',123456)
print(len(obj)) # 4
obj = struct.pack('i',898898789)
print(len(obj)) # 4
# 无论数字多大,打包后长度恒为4
无论哪一端先发送数据
import socket
import struct
client = socket.socket()
client.connect(('127.0.0.1', 9527))
while True:
cmd = input('客户端>>>:')
cmd_bytes = cmd.encode('utf-8')
# 做一个报头
header = struct.pack('i', len(cmd_bytes))
print(len(header))
client.send(header)
# 待服务端确认长度后,发送真实数据长度
client.send(cmd_bytes)
# 接收服务端返回的报头
headers = client.recv(4)
# 解包,接收服务端返回的真实数据
data_len = struct.unpack('i', headers)[0]
result = client.recv(data_len)
print(len(result))
print(result.decode('gbk'))
import socket
import subprocess
import struct
server = socket.socket()
server.bind(('127.0.0.1', 9527))
server.listen(5)
while True:
conn, addr = server.accept()
print(addr)
while True:
try:
# 获取客户端传过来的报头
header = conn.recv(4)
# 解包获取真实数据长度
data_len = struct.unpack('i', header)[0]
# 准备接收真实数据
cmd = conn.recv(data_len)
if len(cmd) == 0:continue
cmd = cmd.decode('utf-8')
if cmd == 'q':
break
# 调用subprocess连接终端,对终端进行操作,并获取操作后正确或错误的结果
obj = subprocess.Popen(
# cmd 接收解码后的字符串
cmd, shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
result = obj.stdout.read() + obj.stderr.read()
print(len(result))
# print(result.decode('gbk')
# 将结果返回给客户端
# 做一个报头,返回给客户端
header = struct.pack('i', len(result))
print(len(header))
conn.send(header)
conn.send(result)
except Exception: break
conn.close()
标签:解决办法 停止 模块 sock byte 套接字 服务器 err list
原文地址:https://www.cnblogs.com/YGZICO/p/11991944.html