05python 解决黏包(python网络编程)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了05python 解决黏包(python网络编程),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含9702字,纯文字阅读大概需要14分钟。
内容图文
![05python 解决黏包(python网络编程)](/upload/InfoBanner/zyjiaocheng/844/3a5c874d11c94c948cc0171d637a70a4.jpg)
上一章对于TCP通信的黏包现象有了一个初步的认识,可以对黏包下个结论什么叫做黏包?
其实就是基于TCP通信的时候当我们发送的数据大于接收端可接受的最大数据范围时,这个时候就会产生拆包现象。在了解了这一现象之后就能够解决黏包。
黏包的两种情况?:一是两个数据特别小,这样会被一次发送出去 ? ? ? ? ? ? ? 二是一条数据特别大啊,会被拆分成很多部分多次发送出去 ? 那么到底要如何解决啦?? ?? ? ?黏包的问题的本质:我们不知道要接受数据的大小? ??? ??? ?首先发送一条信息,显示待发送数据的大小。另一端接收信息,根据显示的大小来 recv( )多大的值? ? ? ?? ?
解决黏包现象
未使用struck模块解决黏包
? ??server端? ??? ? ? 22 ? ? ? ? ? 1
import socket2 3 4
sk = socket.socket()5
sk.bind(('127.0.0.1', 8080))6
sk.listen()7 8
conn, addr = sk.accept()9 10
while True:11
cmd = input('>>>')12
if cmd == 'q':13
conn.send(b'q')14
break15
conn.send(cmd.encode('gbk'))16
num = conn.recv(1024).decode('utf-8')17
conn.send(b'ok')18
res = conn.recv(int(num)).decode('gbk') # recv()里面接收的为数字19
print(res)20 21
conn.close()22
sk.close()? ? ? ? ??client端? ??
? ? ? 25 ? ? ? ? ? 1
import socket2
import subprocess3 4 5
sk = socket.socket()6
sk.connect(('127.0.0.1', 8080))7 8
while True:9
cmd = sk.recv(1024).decode('gbk')10
if cmd == 'q':11
break12
res = subprocess.Popen(cmd, shell=True,13
stdout=subprocess.PIPE,14
stderr=subprocess.PIPE15
)16
std_out = res.stdout.read() # 读取出来的是队列,调用len方法17
# print(std_out.decode('gbk'))18
# print(len(std_out))19
std_err = res.stderr.read()20
sk.send(str(len(std_out) + len(std_err)).encode('utf-8')) # 这里要注意数字是不能encode的21
sk.recv(1024)22
sk.send(std_out)23
sk.send(std_err)24 25
sk.close()? ?
导入struct模块解决黏包问题
struct模块的作用与用法?? ??? ?? ? ??? ??在网络通信当中,大多传递的数据是以二进制流(binary data)存在的。当传递字符串时,不必担心太多的问题,而当传递诸如int、char之类的基本数据的时候,就需要有一种机制将某些特定的结构体类型打包成二进制流的字符串然后再网络传输,而接收端也应该可以通过某种机制进行解包还原出原始的结构体数据。? ??? ? ? server ? ?? ? ? 23 ? ? ? ? ? 1
import socket2
import struct3 4 5
sk = socket.socket()6
sk.bind(('127.0.0.1', 8080))7
sk.listen()8 9
conn, addr = sk.accept()10 11
while True:12
cmd = input('>>>')13
if cmd == 'q':14
conn.send(b'q')15
break16
conn.send(cmd.encode('gbk'))17
num = conn.recv(4)18
num = struct.unpack('i', num)[0]19
res = conn.recv(int(num)).decode('gbk')20
print(res)21 22
conn.close()23
sk.close()? ? ? ? ??client端? ??
? ? ? 22 ? ? ? ? ? 1
import socket2
import struct3
import subprocess4 5 6
sk = socket.socket()7
sk.connect(('127.0.0.1', 8080))8
while True:9
cmd = sk.recv(1024).decode('gbk')10
if cmd == 'q':11
break12
res = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)13
std_out = res.stdout.read()14
std_err = res.stderr.read()15
len_num = len(std_out)+len(std_err)16
num_bytes = struct.pack('i', len_num)17
sk.send(num_bytes)18
sk.send(std_out)19
sk.send(std_err)20 21
sk.close()22 ? ?
补充知识点
? ? ? 38 ? ? ? ? ? 1
# 实现一个大文件的上传和下载2
# 匹配文件 IP地址 端口号3 4
import socket5
import json6 7 8
sk = socket.socket()9
sk.bind(('127.0.0.1', 8090))10
sk.listen()11 12
buffer = 102413
conn, addr = sk.accept()14 15
head_len = conn.recv(4) # 接收四个字节16
head_len = conn.unpack('i', head_len)[0]17
json_head = conn.recv(head_len).decode('utf-8')18
head = json.loads(json_head)19
filesize = head['filesize']20
print(filesize)21 22
with open(r'dir\%s' % head['filename'], 'wb') as f:23
while filesize:24
if filesize >= buffer:25
print(filesize)26
content = conn.recv(buffer)27
f.write(content)28
filesize -= buffer29
else:30
content = conn.recv(filesize)31
f.write(content)32
filesize = 033
print('===>', len(content))34
print(filesize)35 36
print('服务器。。。')37
conn.close()38
sk.close()? ? ? ? ??? ??client端? ??? ??
? ? ? x ? ? ? ? ? 1
import os2
import json3
import struct4
import socket5 6 7
sk = socket.socket()8
sk.connect(('127.0.0.1', 8090))9
buffer = 409610
# 发送文件11
head = {'filepath': r'D:\Documents\oCam',12
'filename': r'test.mp4',13
'filesize': None}14 15
file_path = os.path.join(head['filepath'], head['filename'])16
filesize = os.path.getsize(file_path)17
head['filesize'] = filesize18
json_head = json.dumps(head)19
bytes_head = json_head.encode('utf-8')20
# 计算head的长度21
head_len = len(bytes_head)22
pack_len = struct.pack('i', head_len)23
sk.send(pack_len)24
sk.send(bytes_head)25 26
with open(file_path, 'rb') as f:27
while filesize:28
if filesize >= buffer:29
content = f.read(buffer)30
print('====>', len(content))31
sk.send(content)32
filesize -= buffer33
else:34
content = f.read(filesize)35
sk.send(content)36
filesize = 037 38
sk.close()39 ? ? ? <style></style> <style></style>
内容总结
以上是互联网集市为您收集整理的05python 解决黏包(python网络编程)全部内容,希望文章能够帮你解决05python 解决黏包(python网络编程)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。