粘包问题

什么是粘包问题呢?

在我们写 tcp socket编程的时候,tcp协议是一个流式的协议,服务端第一次发送的数据,客户端无法准确一次性的接收完毕,下一次发送的数据与上一次数据粘在一起。

即:

1、 无法预测对方需要接收的数据大小长度

2、 多次连续发送数据量小的,并且时间间隔短的数据 会一次性打包一起发送

TCP 协议的特性:

​ 会将多次连续发送的数据量小的,并且时间间隔短的数据一次性发送完毕

subprocess模块

我们用subprocess 模块来演示一个粘包问题。

# 服务端
# coding=utf-8
import socket
import subprocess server = socket.socket()
address = ("127.0.0.1",8888)
server.bind(address)
server.listen(5) while True:
conn , addr = server.accept()
while True:
try:
cmd = conn.recv(1024).decode("utf-8")
print(cmd) if cmd == "q":
break obj = subprocess.Popen(
cmd,shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
) res = obj.stdout.read() + obj.stderr.read()
conn.send(res)
except Exception:
break
conn.close()
# 客户端
# coding=utf-8 import socket
client = socket.socket()
address = ("127.0.0.1",8888)
client.connect(address) while True:
cmd = input("请输入>>>")
client.send(cmd.encode("utf-8")) if cmd == "q":
break data = client.recv(1024)
print(data.decode("gbk")) client.close()

终端打印结果

请输入>>>tasklist

映像名称                       PID 会话名              会话#       内存使用
========================= ======== ================ =========== ============
System Idle Process 0 Services 0 24 K
System 4 Services 0 3,172 K
smss.exe 352 Services 0 1,200 K
csrss.exe 464 Services 0 6,656 K
wininit.exe 572 Services 0 5,168 K
csrss.exe 588 Console 1 77,948 K
services.exe 636 Services 0 12,288 K
lsass.exe 652 Services 0 11,164 K
lsm.exe 660 Services 0 4,664 K
winlogon.exe 744 Console 1 8,180 K
svchost.exe 812 Services 0 10,040 K
svchost.
请输入>>>dir
exe 892 Services 0 8,280 K
svchost.exe 980 Services 0 21,744 K
svchost.exe 168 Services 0 21,060 K
svchost.exe 388 Services 0 40,792 K
svchost.exe 908 Services 0 12,252 K
WUDFHost.exe 1100 Services 0 8,096 K
ZhuDongFangYu.exe 1188 Services 0 23,784 K
svchost.exe 1236 Services 0 17,532 K
wlanext.exe 1412 Services 0 5,268 K
conhost.exe 1420 Services 0 2,860 K
dwm.exe 1536 Console 1 38,436 K
explorer.exe 1588 Console 1 70,028 K
spoolsv.exe 1612 Services 0 12,204 K
svchost.exe

我们看到在输完tasklist 命令之后,再次输入其他命令,还是上次命令的结果,

那么久证明了 服务端第一次发送的数据,客户端无法准确一次性的接收完毕,下一次发送的数据与上一次数据粘在一起。我们在客户端接收的时候,接收的数据大小是1024个字节,服务器执行结果 超出了接收的大小,所以相当于把结果堆到了后面,一起发送,所以下次执行命令得不到正确的结果,那么我们需要解决这个问题就需要用到 struct 模块

struct模块

struct 模块必须先定义报头,,先发送报头,再发送真实数据

# 服务端
# coding=utf-8 import struct
import socket
import subprocess server = socket.socket()
address = ("127.0.0.1",8888)
server.bind(address)
server.listen(5) while True:
conn,addr = server.accept()
while True:
try:
cmd = conn.recv(1024).decode("utf-8")
print(cmd) if cmd == "q":
break obj = subprocess.Popen(
cmd ,shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
) res = obj.stdout.read() + obj.stderr.read() # 将执行结果计算长度用i模式打包
res_len = struct.pack("i",len(res)) # 先发送数据长度
conn.send(res_len) # 再发送真实数据
conn.send(res)
except Exception:
break
conn.close()
# 客户端
# coding=utf-8 import socket
import struct client = socket.socket()
address = ("127.0.0.1",8888)
client.connect(address) while True:
cmd = input("请输入命令>>>")
client.send(cmd.encode("utf-8"))
if cmd == "q":
break # 用struct模块接收的长度统一是4个字节,
head = client.recv(4)
# 然后用struct模块解包得到数据的真实长度,返回的是元组类型,0表示第一个元素,就是真实长度
data_len = struct.unpack("i",head)[0] # 然后再把真实长度接收即可。
data = client.recv(data_len)
print(data.decode("gbk"))
client.close()

UDP协议编程

udp也是一种传输协议

1)不需要建立双向通道

2)不会粘包

3)客户端给服务端发送数据,不需要等待服务端返回接收成功

4)数据容易丢失,数据不安全。

TCP:就相当于与在打电话

UDP:就相当于与在发短信

简易qq聊天室

# 服务端
# coding=utf-8
import socket server = socket.socket(type=socket.SOCK_DGRAM)
address = ("127.0.0.1",8888)
server.bind(address) while True:
msg,addr = server.recvfrom(1024)
print(msg.decode("utf-8")) # 服务端往客户端发送消息
send_msg = input("服务端发送消息")
server.sendto(send_msg.encode("utf-8"),addr)
# 客户端
# coding=utf-8
import socket
client = socket.socket(type=socket.SOCK_DGRAM)
address = ("127.0.0.1",8888) while True:
send_msg = input("请输入信息")
client.sendto(send_msg.encode("utf-8"),address) data = client.recv(1024)
print(data.decode("utf-8"))

Python-网络编程之粘包、UDP的更多相关文章

  1. Python网络编程,粘包、分包问题的解决

    tcp编程中的粘包.分包问题的解决: 参考:https://blog.csdn.net/yannanxiu/article/details/52096465 服务端: #!/bin/env pytho ...

  2. python网络编程之粘包

    一.什么是粘包 须知:只有TCP有粘包现象,UDP永远不会粘包 粘包不一定会发生 如果发生了:1.可能是在客户端已经粘了 2.客户端没有粘,可能是在服务端粘了 首先需要掌握一个socket收发消息的原 ...

  3. python网络编程-socket“粘包”(小数据发送问题)

    一:什么是粘包 “粘包”, 即服务器端你调用时send 2次,但你send调用时,数据其实并没有立刻被发送给客户端,而是放到了系统的socket发送缓冲区里,等缓冲区满了.或者数据等待超时了,数据才会 ...

  4. Python之路 - 网络编程之粘包

    Python之路 - 网络编程之粘包 粘包

  5. python/socket编程之粘包

    python/socket编程之粘包 粘包 只有TCP有粘包现象,UDP永远不会粘包. 首先需要掌握一个socket收发消息的原理 发送端可以是1k,1k的发送数据而接受端的应用程序可以2k,2k的提 ...

  6. python 网络编程 TCP/IP socket UDP

    TCP/IP简介 虽然大家现在对互联网很熟悉,但是计算机网络的出现比互联网要早很多. 计算机为了联网,就必须规定通信协议,早期的计算机网络,都是由各厂商自己规定一套协议,IBM.Apple和Micro ...

  7. python socket网络编程之粘包问题详解

    一,粘包问题详情 1,只有TCP有粘包现象,UDP永远不会粘包 你的程序实际上无权直接操作网卡的,你操作网卡都是通过操作系统给用户程序暴露出来的接口,那每次你的程序要给远程发数据时,其实是先把数据从用 ...

  8. Python全栈-网络编程-TCP粘包

    一.什么是TCP粘包 C/S架构下,接收方不知道每个消息的发送间隙.也不知道每次应该提取多少个字节的数据,与此同时,TCP是面向连接的,面向流的,收发两端都要有,因此发送端为了将多个发往接收端的数据包 ...

  9. 《Python网络编程》学习笔记--UDP协议

    第二章中主要介绍了UDP协议 UDP协议的定义(转自百度百科) UDP是OSI参考模型中一种无连接的传输层协议,它主要用于不要求分组顺序到达的传输中,分组传输顺序的检查与排序由应用层完成,提供面向事务 ...

  10. UNIX网络编程——Socket粘包问题

    一.两个简单概念长连接与短连接:1.长连接 Client方与Server方先建立通讯连接,连接建立后不断开, 然后再进行报文发送和接收. 2.短连接 Client方与Server每进行一次报文收发交易 ...

随机推荐

  1. taskFactory

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  2. 剑指offer——21正则表达式匹配

    题目描述 请实现一个函数用来匹配包括'.'和'*'的正则表达式.模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次). 在本题中,匹配是指字符串的所有字符匹配整个模式 ...

  3. 关于private,default,protected,public,成员变量访问权限

    关于private,protected,public,default成员变量的访问权限,请参阅上图! 子类要访问父类的private成员变量,必须采用采用get方法: eg: public class ...

  4. USACO2008 Patting Heads /// 筛数 oj24705

    题目大意: N (1 < N < 100,000)头牛被编号为1-N,围坐成圈 每头牛都被画上数字Ai (1 ≤ Ai ≤ 1,000,000),可能重复 逐个起来拍打 其他身上的数字是 ...

  5. USACO2012 Broken necklace /// DP oj10103

    题目大意: 项链最长的纯色连续段,“w”即white白色珠子,可任意涂为红或蓝,“r” “b”即红 蓝. Input Line 1:  N, the number of beads Line 2:   ...

  6. python接口自动化(get请求)

    python接口自动化(get请求) get请求的目的:查询资源 一.导包 二.请求的URL 三.请求的参数 四.获取请求的URL 五.获取响应的状态码 六.获取响应的本文信息 #导包 import ...

  7. Hadoop Pig组件

  8. ReentrantLock中的公平锁与非公平锁

    简介 ReentrantLock是一种可重入锁,可以等同于synchronized的使用,但是比synchronized更加的强大.灵活. 一个可重入的排他锁,它具有与使用 synchronized ...

  9. p分位数的原理及计算

    p分位数的原理及计算 大纲>> 1.统计上的分位数概念   2.分位数的计算方法及举例 2.1首先确定p分位数的位置(依据项数分为基数.偶数情况) 2.2 求上一步确定的p分位数位置处的具 ...

  10. SQL Server Download

    { https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads }