Python-网络编程之粘包、UDP
粘包问题
什么是粘包问题呢?
在我们写 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的更多相关文章
- Python网络编程,粘包、分包问题的解决
tcp编程中的粘包.分包问题的解决: 参考:https://blog.csdn.net/yannanxiu/article/details/52096465 服务端: #!/bin/env pytho ...
- python网络编程之粘包
一.什么是粘包 须知:只有TCP有粘包现象,UDP永远不会粘包 粘包不一定会发生 如果发生了:1.可能是在客户端已经粘了 2.客户端没有粘,可能是在服务端粘了 首先需要掌握一个socket收发消息的原 ...
- python网络编程-socket“粘包”(小数据发送问题)
一:什么是粘包 “粘包”, 即服务器端你调用时send 2次,但你send调用时,数据其实并没有立刻被发送给客户端,而是放到了系统的socket发送缓冲区里,等缓冲区满了.或者数据等待超时了,数据才会 ...
- Python之路 - 网络编程之粘包
Python之路 - 网络编程之粘包 粘包
- python/socket编程之粘包
python/socket编程之粘包 粘包 只有TCP有粘包现象,UDP永远不会粘包. 首先需要掌握一个socket收发消息的原理 发送端可以是1k,1k的发送数据而接受端的应用程序可以2k,2k的提 ...
- python 网络编程 TCP/IP socket UDP
TCP/IP简介 虽然大家现在对互联网很熟悉,但是计算机网络的出现比互联网要早很多. 计算机为了联网,就必须规定通信协议,早期的计算机网络,都是由各厂商自己规定一套协议,IBM.Apple和Micro ...
- python socket网络编程之粘包问题详解
一,粘包问题详情 1,只有TCP有粘包现象,UDP永远不会粘包 你的程序实际上无权直接操作网卡的,你操作网卡都是通过操作系统给用户程序暴露出来的接口,那每次你的程序要给远程发数据时,其实是先把数据从用 ...
- Python全栈-网络编程-TCP粘包
一.什么是TCP粘包 C/S架构下,接收方不知道每个消息的发送间隙.也不知道每次应该提取多少个字节的数据,与此同时,TCP是面向连接的,面向流的,收发两端都要有,因此发送端为了将多个发往接收端的数据包 ...
- 《Python网络编程》学习笔记--UDP协议
第二章中主要介绍了UDP协议 UDP协议的定义(转自百度百科) UDP是OSI参考模型中一种无连接的传输层协议,它主要用于不要求分组顺序到达的传输中,分组传输顺序的检查与排序由应用层完成,提供面向事务 ...
- UNIX网络编程——Socket粘包问题
一.两个简单概念长连接与短连接:1.长连接 Client方与Server方先建立通讯连接,连接建立后不断开, 然后再进行报文发送和接收. 2.短连接 Client方与Server每进行一次报文收发交易 ...
随机推荐
- 剑指offer——06二叉树的下一个节点
题目描述 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 题目的意思是,在一颗二叉树的中序遍历中,给出其中一 ...
- solr添加IK分词和自己定义词库
下载IK分词IK Analyzer 2012FF_hf1.zip 下载地址:http://yunpan.cn/cdvATy8899Lrw (提取码:c10d) 1.将IKAnalyzer2012FF_ ...
- 为什么 TCP 建立连接是三次握手,关闭连接确是四次挥手呢?
Java技术栈 www.javastack.cn 优秀的Java技术公众号 作者:小书go https://blog.csdn.net/qzcsu/article/details/72861891 背 ...
- <pygame> 打飞机(小游戏)
0.游戏的基本实现 ''' 游戏的基本实现 游戏的初始化:设置游戏窗口,绘制图像的初始位置,设定游戏时钟 游戏循环:设置刷新频率,检测用户交互,更新所有图像位置,更新屏幕显示 ''' 1.安装pyga ...
- 13-Ubuntu-查阅终端命令版本信息和帮助信息
查看版本信息: 终端命令 --version 查看帮助信息: 终端命令 --help 注: 待查阅的命令 后面有两个减号-- 例:查看终端命令ls的版本和帮助信息 ls --version ls -- ...
- jdbc_mysql----interset
- Window sevice +OWIN+webapi
webapi正常都托管在iis上,这里引入owin,将其托管在window服务上. 第一步:创建一个服务,这里就不多描述. 第二步:引入OWIN 2.1引入bll 2.2加入api路由配置 publi ...
- sql (12) HAVING
HAVING 子句在 SQL 中增加 HAVING 子句原因是,WHERE 关键字无法与合计函数一起使用. 新建表 StudentSS_id Grade Name phone1 98 小明 12345 ...
- Windows 设置内网和外网同时使用
想要电脑同时使用内网和外网必须具备两个网卡,一个是无线网卡一个是本地连接,无线网卡用来连接wifi也就是外网,而本地连接需要网线连接内网,外网是不需要做设置的,我们只需要设置内网即可,鼠标右击电脑右下 ...
- 弹性网卡支持私网多IP
摘要: 弹性网卡支持多IP功能可以最多在一块弹性网卡配置20个私网IP地址,特别适用于于以下场景. 1.单个服务器上托管多个应用,提升实例利用率,每个应用对外暴露一个独立的服务IP地址. 2.当实例发 ...