python笔记(解决TCP黏包问题)

@几个重要的协议:tcp,udp,ip,arp
@应用层的协议:http(https),ftp,smtp(邮件相关的协议)
解决黏包问题
一、为什么会出现黏包现象?
(1)首先只有在TCP协议中才会出现黏包现象。
(2)是因为CP协议是面向流的协议。
(3)在发送的数据传输的过程中还有缓存机制来避免数据丢失。
(4)并因此在连续发送小数据的时候以及接收大小不符的时候都容易出现黏包现象。
(5)本质还是因为我们在接收数据的时候不知道发送的数据的长短。
(6)解决新包问题并在传输大量数据之前先告诉接收端要发送的数据大小。

1、黏报现象:数据已经乱了,没接收完,接收多了
UDP:不会黏包,但丢包
在这里插入图片描述
TCP:会黏包,但不丢包(优化算法)

解决黏包问题:
好处:确定了我到底要接收多大的数据
1、要在文件中配置一个配置项:就是每一次recy的大小 buffer=4096
2、当我们要发送大数据的时候,要明确的告诉接收方要发送多大的数据,以便接收方能够准确的接收到所有数据
3、 多用在文件传输的过程中
(1)大文件的传输一定是按照字读每一次读固定的字节
(2)传输的过程中一边读一边传接收端一边收一边写

一、struct模块

import struct
ret = struct.pack('i',4096)  #'i'代表int,就是把一个数字转换成固定长度的bytes类型(4个字节)
print(ret,len(ret))

num = struct.unpack('i',ret)
print(num[0])

输出结果:

b’\x00\x10\x00\x00’ 4
4096

在这里插入图片描述
二、解决例子(在server端下发命令在client端接收命令)
TCP---->server:

import struct
import socket

sk = socket.socket()
sk.bind(('127.0.0.1',8090))
sk.listen(5)
conn,addr = sk.accept()
while True:
    cmd = input('>>')
    if cmd == 'q':
        conn.send(b'q')
        break
    conn.send(cmd.encode('gbk'))
    num = conn.recv(4) #4
    num = struct.unpack('i',num)[0]
    res = conn.recv(int(num)).decode('gbk')
    print(res)
conn.close()
sk.close()

TCP---->client:

import struct
import socket
import subprocess

sk = socket.socket()
sk.connect(('127.0.0.1',8090))

while True:
    cmd = sk.recv(1024).decode('gbk')
    if cmd == 'q':
        break
    res = subprocess.Popen(cmd,shell=True,
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE
                           )
    std_out = res.stdout.read()
    std_err = res.stderr.read()
    len_num = len(std_out) + len(std_err)
    num_by = struct.pack('i',len_num)
    sk.send(num_by)
    sk.send(std_out)
    sk.send(std_err)
sk.close()

猜你喜欢

转载自blog.csdn.net/qq_41433183/article/details/84585805