tcp: 属于长连接,与一个客户端进行连接了以后,其他的客户端要等待.要想连接另外一个客户端,需要优雅地断开当前客户端的连接

允许地址重用:
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
在bind IP地址和端口之前,写这句话,防止端口被占用无法使用. 缓冲区:
输入缓冲区 # recv
输出缓冲区 # send

什么是缓冲区,为什么会有缓冲区?
缓冲区: 暂时存放传输数据的地方.
每个socket对象被创建后,都会分配两个缓冲区,输入缓冲区和输出缓冲区. 当发送消息的时候,
先将数据写入输出缓冲区中,再由TCP/UDP协议将数据从缓冲区发送到目标机器. 一旦数据写入到缓冲区,
无论是否发送到目标机器,程序都可以执行下一步操作,这样可以防止网络不畅通造成的程序阻塞.
当接收数据的时候,会从输入缓冲区中读取数据,而不是直接从网络中读取,这样cpu可以处理完当前任务后从输入缓冲区读取信息. 参考: 缓冲区与缓存
MTU:最大传输单元(Maximum Transmission Unit)
  网络层限制是1518b,每次发送数据的时候最好不要超过这个数 粘包(tcp的两种粘包现象)
1. 连续发送小的数据,并且每次发送之间的时间间隔很短. (两个消息在输出缓冲区粘连到一起)
原因是tcp为了传输效率,做了一个优化算法(Nagle),减少连续的小包发送.因为每一个消息被包裹以后都会有两个过程:
1. 组包 2. 拆包0, 会降低效率
2. 第一次服务端发送的数据比客户端设置的一次接收消息的size要大, 一次接收不完,第二次接收的时候就会把第一次剩余的消息接收到. 粘包的根本原因: 双方不知道对方发送消息的大小.
解决方案1:
发送消息之前,先计算要发送消息的长度,然后先将消息长度发送过去,对方回复确认收到,
然后根据接收到的消息长度来修改自己一次接收消息的大小.
这个过程多了一次交互 解决方案2:
第一种粘包情况可以增加发送消息的时间间隔,等缓冲区的消息发送成功后再发送后续消息 解决方案3:
# 粘包现象1 服务端

import socket

server = socket.socket()
ip_port = ('192.168.15.87', 8001)
server.bind(ip_port) server.listen() conn,addr = server.accept() from_client_msg1 = conn.recv(1024).decode('utf-8')
#2000B -- 1024 976B + 1000B
from_client_msg2 = conn.recv(1024).decode('utf-8')
#976+48 = 1024
print('msg1:',from_client_msg1)
print('msg2:',from_client_msg2) conn.close()
server.close()
# 粘包现象1 客户端
import socket client = socket.socket()
server_ip_port = ('192.168.15.87', 8001)
client.connect(server_ip_port)
client.send('你好!'.encode('utf-8'))
client.send('天气真好~'.encode('utf-8')) client.close()
# 粘包现象_2_服务端
import socket
import subprocess server = socket.socket()
ip_port = ('192.168.15.87', 8001)
server.bind(ip_port)
server.listen(3) while 1:
print('等待连接中...')
tube, addr = server.accept()
print('连接成功!')
while 1:
print('等待接收消息中...')
cmd = tube.recv(1024).decode('utf-8')
print('接收命令:%s' % cmd)
if cmd == 'exit':
tube.close()
print('连接已断开!')
break
sub_obj = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
content = sub_obj.stdout.read() # byte类型,gbk编码
error = sub_obj.stderr.read()
len_of_content = str(len(content)).encode('utf-8')
len_of_error = str(len(error)).encode('utf-8')
if len(content) == 0:
print('即将发送消息长度为%s' % len(error))
tube.send(len_of_error)
tube.send(error) else:
print('即将发送消息长度为%s' % len(content))
tube.send(len_of_content)
reply = tube.recv(1024).decode('utf-8')
if reply == 'ack':
print(reply)
tube.send(content)
# 粘包现象_2_客户端
import socket client = socket.socket()
server_ip_port = ('192.168.15.87', 8001)
client.connect(server_ip_port) while 1:
cmd = input('请输入命令>>>')
client.send(cmd.encode('utf-8'))
if cmd == 'exit':
client.close()
break
len_of_msg = int(client.recv(1024).decode('utf-8'))
print('即将接收的消息长度为:%s' % len_of_msg)
client.send('ack'.encode('utf-8'))
msg = client.recv(len_of_msg)
print('实际接收到的消息长度为:%s' % len(msg))
print(msg.decode('gbk'))

Day29--Python--缓冲区, 粘包的更多相关文章

  1. Python之粘包

    Python之粘包 让我们基于tcp先制作一个远程执行命令的程序(1:执行错误命令 2:执行ls 3:执行ifconfig) 注意注意注意: res=subprocess.Popen(cmd.deco ...

  2. Python进阶----粘包,解决粘包(旗舰版)

    Python进阶----粘包,解决粘包(旗舰版) 一丶粘包 只有TCP有粘包现象,UDP永远不会粘包 什么是粘包     存在于客户端接收数据时,不能一次性收取全部缓冲区中的数据.当下一次再有数据来时 ...

  3. python 解决粘包问题

    客户端发送hello,如果服务端 recv(1) ,那只能接收到 h 这一个字符,然后再recv(1) 一下,可以再接收一个 e , 因为客户端发送的结果长,所以只能把其他的先缓存下来,下次recv的 ...

  4. 缓冲区 粘包 029 send 和sendall 的区别 find 和 findall 的区别

    一.tcp : 属于长连接 与客户端连接了之后 其他客户端需要等待 要连接另外一个 必须优雅的断开前面这个客户的连接. 二.缓冲区 :为了避免网络传输信号不通畅而是程序一直停留在消息发送状态而不向下进 ...

  5. Python socket 粘包

    目录 1 TCP的三次握手四次挥手 0 1.1 三次握手 1 1.2 四次挥手 2 2 粘包现象 3 2.1 基于TCP制作远程执行命令操作(win服务端) 4 2.1 基于TCP制作远程执行命令操作 ...

  6. Python socket粘包解决

    socket粘包: socket 交互send时,连续处理多个send时会出现粘包,soket会把两条send作为一条send强制发送,会粘在一起. send发送会根据recv定义的数值发送一个固定的 ...

  7. Python socket粘包问题(最终解决办法)

    套接字: 就是将传输层以下的协议封装成子接口 对于应用程序来说只需调用套接字的接口,写出的程序自然是遵循tcp或udp协议的 实现第一个功能个:实现:通过客户端向服务端发送命令,调取windows下面 ...

  8. Python socket粘包问题(初级解决办法)

    server端配置: import socket,subprocess,struct from socket import * server=socket(AF_INET,SOCK_STREAM) s ...

  9. python socket粘包及实例

    1.在linux中经常出现粘包的出现(因为两个send近靠着,造成接受到的数据是在一起的.)解决方法: 在服务端两send的中间中再添加一个recv(),客户端添加一个send(),服务端收到信息确认 ...

  10. python tcp 粘包问题解决、文件下载等

    from socket import * #以下是关于tcp:服务端 和 客户端的小例子#服务端socket_server = socket(AF_INET, SOCK_STREAM) socket_ ...

随机推荐

  1. react 入坑笔记(五) - 条件渲染和列表渲染

    条件渲染和列表渲染 一.条件渲染 条件渲染较简单,使用 JavaScript 操作符 if 或条件运算符来创建表示当前状态的元素,然后让 React 根据它们来更新 UI. 贴一个小栗子: funct ...

  2. hdu-1686(kmp)

    题意:前面的都是废话...其实直接看输入要求和输出要求就可以了,就是给你两个字符串,问你第一个字符串在第二个字符串中出现几次: 解题思路:kmp... 代码: #include<iostream ...

  3. python基础数据类型—int、bool、字符串的常用方法

    1.int int为整型数据,主要用于计算和类型转化(将字符串转为数字) 常用方法 #bit_length()当用二进制表示数字时所用最少位数,如下十进制数12用二进制表示是1100(bin),所以# ...

  4. POJ 2299 -Ultra-QuickSort-树状数组求逆序数

    POJ 2299Ultra-QuickSort 使用树状数组记录逆序对数. 把数组按照大小顺序插入,getsum(i)就是i前面的比他大的数. #include <cstdio> #inc ...

  5. Codeforces734 E. Anton and Tree

    传送门:>Here< 题意:给出一颗树,节点不是黑色就是白色,每次可以将一个颜色相同的块变颜色,问最少变几次才能让其变为同色 解题思路: 我们考虑由于每一次都是把同样颜色的色块进行变色,因 ...

  6. 【XSY1515】【GDKOI2016】小学生数学题 组合数学

    题目描述 给你\(n,k,p\)(\(p\)为质数),求 \[ \sum_{i=1}^n\frac{1}{i}\mod p^k \] 保证有解. \(p\leq {10}^5,np^k\leq {10 ...

  7. HDOJ5540 Secrete Master Plan

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5540 题目大意:给一个两个2*2的矩阵,第二个矩阵能不能通过旋转得到第一个矩阵 题目思路:模拟 #in ...

  8. hiho1257 Snake Carpet

    题目链接:http://hihocoder.com/problemset/problem/1257 题目大意:有n条蛇 编号为1-n 每条蛇的长度跟编号相等 奇数编号的蛇必须拐奇数次(除了第一条)偶数 ...

  9. 反射中Class.forName()和classLoader的区别

    搞清楚两者之间区别前,我们来了解下类加载过程. 一.类加载过程 1.加载 通过一个类的全限定名来获取定义此类的二进制字节流. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构. 在内存中生 ...

  10. 自学华为IoT物联网_09 OceanConnect业务流程

    点击返回自学华为IoT物流网 自学华为IoT物联网_09 OceanConnect业务流程 1.  物流网重要的连个协议介绍 1.1  重要物联网协议介绍----MQTT MQTT(消息队列遥测传输) ...