day27_粘包问题与struct模块

1、粘包问题

问题描述:

当客户端设定的最大接收字节数(bytes size)小于服务端发来的数据时,多余的部分数据,会在下一次的客户端接收时,一起传过来,先接收完之前没接收到的数据,才会继续接收后面的数据。这个特性跟tcp的协议特性有关,因为tcp协议是一个可靠的传输协议,

演示:

# 客户端.py
import socket

client = socket.socket()
client.connect(('127.0.0.1',10086))
while True:
    cmd = input('cmd>>:').encode('utf8')
    client.send(cmd)
    result = client.recv(1024).decode('gbk')  # 指定接收数据的最大字节数1024
    print(f'>>{result}')
    if result == 'q':
        break
# 服务器.py
import socket
import subprocess

server = socket.socket()
server.bind(('127.0.0.1', 10086))
server.listen(5)

while True:
    conn, addr = server.accept()  # 链接客户端
    print(f'{addr}:')
    while True:
        try:
            cmd = conn.recv(1024).decode('utf8')
            print(f'from client:{cmd}')
            if cmd == 'q':
                conn.send(cmd.encode('utf8'))
                break

            # 1 subprocess.Popen()
            obj = subprocess.Popen(
                cmd,
                shell=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE
            )
            restult = obj.stdout.read() + obj.stderr.read()
            print(restult.decode('gbk'))
            conn.send(restult)
            print('to client success')
        except Exception as e:
            print(f'e:{e}')
            break
    conn.close()  # 执行命令出错或者与该客户端的链接已断开

先执行命令tasklist,再执行命令dir

实际执行的结果:

('127.0.0.1', 59338):
from client:tasklist

映像名称                       PID 会话名              会话#       内存使用 
========================= ======== ================ =========== ============
System Idle Process              0 Services                   0          8 K
System                           4 Services                   0     27,848 K
Registry                        96 Services                   0     41,200 K
smss.exe                       360 Services                   0        924 K
csrss.exe                      600 Services                   0      5,272 K
wininit.exe                    700 Services                   0      6,332 K
csrss.exe                      728                            1      4,888 K
services.exe                   776 Services                   0      8,612 K
lsass.exe                      848 Services                   0     21,060 K
svchost.exe                    984 Services                   0      3,596 K
fontdrvhost.exe               1008 Services                   0      3,048 K
svchost.exe                    560 Services                   0     31,540 K
svchost.exe                    556 Services                   0     14,772 K
svchost.exe                    868 Services                   0      7,908 K
svchost.exe                   1204 Services                   0     10,228 K
svchost.exe                   1292 Services                   0     11,932 K
svchost.exe                   1408 Services                   0     15,228 K
svchost.exe                   1420 Services                   0     14,044 K
svchost.exe                   1448 Services                   0      6,972 K
svchost.exe                   1480 Services                   0      5,564 K
svchost.exe                   1540 Services                   0     10,392 K
svchost.exe                   1676 Services                   0      9,800 K
svchost.exe                   1732 Services                   0     10,412 K
svchost.exe                   1744 Services                   0      7,556 K
svchost.exe                   1832 Services                   0      6,088 K
svchost.exe                   1876 Services                   0      7,380 K
svchost.exe                   1980 Services                   0     11,536 K
svchost.exe                   2016 Services                   0      9,724 K
svchost.exe                   2024 Services                   0      8,128 K
svchost.exe                   1324 Services                   0     15,104 K
svchost.exe                   2072 Services                   0      8,828 K
svchost.exe                   2312 Services                   0     74,900 K
svchost.exe                   2320 Services                   0      5,548 K
svchost.exe                   2328 Services                   0      6,796 K
Memory Compression            2376 Services                   0    177,844 K
svchost.exe                   2432 Services                   0      8,372 K
igfxCUIService.exe            2456 Services                   0      8,080 K
svchost.exe                   2488 Services                   0      7,336 K
svchost.exe                   2504 Services                   0      6,944 K
svchost.exe                   2528 Services                   0     12,032 K
svchost.exe                   2596 Services                   0     15,732 K
svchost.exe                   2796 Services                   0     12,952 K
svchost.exe                   3008 Services                   0     12,456 K
svchost.exe                   3016 Services                   0      6,312 K
svchost.exe                   3160 Services                   0     14,784 K
svchost.exe                   3340 Services                   0     12,744 K
svchost.exe                   3436 Services                   0     15,116 K
spoolsv.exe                   3684 Services                   0     13,680 K
svchost.exe                   3752 Services                   0      7,060 K
svchost.exe                   3836 Services                   0     14,512 K
svchost.exe                   4020 Services                   0     18,512 K
svchost.exe                   4052 Services                   0      7,924 K
svchost.exe                   4144 Services                   0      5,932 K
svchost.exe                   4440 Services                   0     26,732 K
svchost.exe                   4448 Services                   0     15,712 K
NVDisplay.Container.exe       4496 Services                   0      8,676 K
svchost.exe                   4516 Services                   0     12,176 K
QQProtect.exe                 4524 Services                   0     18,996 K
svchost.exe                   4532 Services                   0     11,836 K
svchost.exe                   4548 Services                   0      6,024 K
svchost.exe                   4556 Services                   0     10,664 K
svchost.exe                   4564 Services                   0     10,396 K
svchost.exe                   4580 Services                   0      7,404 K
svchost.exe                   4600 Services                   0     42,908 K
GATESRV.exe                   4620 Services                   0      6,112 K
svchost.exe                   4716 Services                   0      5,304 K
svchost.exe                   4732 Services                   0      8,200 K
svchost.exe                   4756 Services                   0     21,012 K
svchost.exe                   5084 Services                   0      5,108 K
svchost.exe                   5576 Services                   0      8,456 K
svchost.exe                   5640 Services                   0     10,528 K
svchost.exe                   2180 Services                   0      7,480 K
svchost.exe                   4432 Services                   0      8,772 K
svchost.exe                   6980 Services                   0     12,688 K
svchost.exe                   4672 Services                   0     15,708 K
dllhost.exe                   5772 Services                   0     10,272 K
svchost.exe                   9144 Services                   0     29,256 K
SecurityHealthService.exe     8528 Services                   0     15,140 K
svchost.exe                   1464 Services                   0     10,796 K
svchost.exe                   9384 Services                   0      7,320 K
svchost.exe                   8208 Services                   0     17,708 K
svchost.exe                   1336 Services                   0     13,000 K
svchost.exe                   4724 Services                   0     10,008 K
svchost.exe                   4376 Services                   0     22,892 K
SgrmBroker.exe                7020 Services                   0      5,620 K
svchost.exe                   9472 Services                   0      8,920 K
svchost.exe                   5484 Services                   0      8,060 K
svchost.exe                  10108 Services                   0      7,052 K
csrss.exe                     8356                            2      5,052 K
svchost.exe                   7412 Services                   0      6,528 K
svchost.exe                   1456 Services                   0      7,124 K
svchost.exe                   9368 Services                   0      9,164 K
csrss.exe                     9124 Console                    3      5,320 K
winlogon.exe                 13408 Console                    3      8,928 K
fontdrvhost.exe              10280 Console                    3     16,588 K
dwm.exe                       4296 Console                    3     88,868 K
nvxdsync.exe                 12712 Console                    3     19,060 K
MasterHelper.exe              7184 Console                    3      9,572 K
ProcHelper64.exe              3524 Console                    3      5,904 K
sihost.exe                    9328 Console                    3     29,792 K
svchost.exe                  13808 Console                    3     24,296 K
svchost.exe                   7432 Console                    3     27,012 K
taskhostw.exe                12168 Console                    3     17,956 K
igfxEM.exe                    9972 Console                    3     10,632 K
igfxHK.exe                    7480 Console                    3      8,012 K
igfxTray.exe                  4816 Console                    3      9,072 K
explorer.exe                 12068 Console                    3    139,020 K
ctfmon.exe                   10464 Console                    3     39,232 K
svchost.exe                   2632 Services                   0      7,232 K
svchost.exe                  13724 Console                    3     18,416 K
ChsIME.exe                   14256 Console                    3     53,544 K
ShellExperienceHost.exe      11296 Console                    3     61,556 K
SearchUI.exe                  6852 Console                    3     99,068 K
RuntimeBroker.exe             4028 Console                    3     42,096 K
RuntimeBroker.exe             6360 Console                    3     20,324 K
MicrosoftEdge.exe            13212 Console                    3    104,060 K
ApplicationFrameHost.exe     11024 Console                    3     34,516 K
YourPhone.exe                 1148 Console                    3     35,692 K
browser_broker.exe            1712 Console                    3     15,636 K
dllhost.exe                   2812 Console                    3     13,928 K
dllhost.exe                  11352 Console                    3      5,928 K
RuntimeBroker.exe             3424 Console                    3     14,736 K
RuntimeBroker.exe            10328 Console                    3     34,520 K
MicrosoftEdgeCP.exe           7380 Console                    3    134,968 K
MicrosoftEdgeSH.exe           6896 Console                    3     15,388 K
SettingSyncHost.exe          12512 Console                    3      4,428 K
WindowsInternal.Composabl    14172 Console                    3     41,328 K
svchost.exe                   4744 Services                   0      5,000 K
RuntimeBroker.exe             4360 Console                    3      9,768 K
StudentMain.exe              10956 Console                    3     40,304 K
RAVCpl64.exe                 11952 Console                    3     11,476 K
RAVBg64.exe                   5556 Console                    3     10,520 K
WeChat.exe                    6880 Console                    3     96,068 K
WeChatWeb.exe                 9584 Console                    3     16,996 K
SystemSettings.exe            1192 Console                    3        324 K
svchost.exe                   2420 Console                    3     25,104 K
RuntimeBroker.exe            11132 Console                    3     24,920 K
WinStore.App.exe             14320 Console                    3        324 K
FeiQ.exe                     12912 Console                    3     15,604 K
Microsoft.Photos.exe          4004 Console                    3     39,640 K
RuntimeBroker.exe             3504 Console                    3     30,476 K
mcool.exe                     1044 Console                    3     28,652 K
audiodg.exe                   5612 Services                   0     18,492 K
FMAPP.exe                     7660 Console                    3      7,892 K
pycharm64.exe                10456 Console                    3    864,072 K
fsnotifier64.exe             13792 Console                    3      1,692 K
conhost.exe                  11980 Console                    3      4,912 K
OfficeClickToRun.exe         12488 Services                   0     47,996 K
AppVShNotify.exe              8992 Services                   0      6,072 K
AppVShNotify.exe             13048 Console                    3      6,680 K
SearchIndexer.exe             6804 Services                   0     53,196 K
Typora.exe                    3880 Console                    3    112,520 K
Typora.exe                    9268 Console                    3     83,152 K
Typora.exe                    8636 Console                    3     69,700 K
Typora.exe                   14132 Console                    3    138,072 K
Notepad++.exe                 1196 Console                    3     45,280 K
smartscreen.exe                592 Console                    3     28,508 K
svchost.exe                  10016 Services                   0      7,472 K
Windows.WARP.JITService.e    13884 Services                   0      5,248 K
svchost.exe                   6592 Services                   0     13,464 K
MicrosoftEdgeCP.exe           8012 Console                    3     64,236 K
MicrosoftEdgeCP.exe           9224 Console                    3     98,264 K
MicrosoftEdgeCP.exe           8264 Console                    3    117,192 K
MicrosoftEdgeCP.exe           6940 Console                    3     27,632 K
MicrosoftEdgeCP.exe          13372 Console                    3     27,436 K
SearchProtocolHost.exe        8164 Services                   0     10,056 K
SearchProtocolHost.exe        9220 Console                    3      7,688 K
SearchFilterHost.exe          8964 Services                   0      6,248 K
python.exe                    9808 Console                    3     31,436 K
conhost.exe                  11172 Console                    3     11,040 K
python.exe                   10020 Console                    3     31,536 K
conhost.exe                   1232 Console                    3     11,044 K
cmd.exe                       6468 Console                    3      3,944 K
tasklist.exe                 13424 Console                    3      7,652 K
WmiPrvSE.exe                 13964 Services                   0      8,536 K

to client success
from client:dir
 驱动器 D 中的卷是 DATA
 卷的序列号是 AE05-5DDC

 D:\Python\python学习—上海老男孩\PycharmProjects\网络编程 的目录

2019/10/18  16:47    <DIR>          .
2019/10/18  16:47    <DIR>          ..
2019/10/18  17:00    <DIR>          .idea
2019/10/18  15:45               186 test.py
2019/10/18  16:31               325 客户端.py
2019/10/18  16:47               998 服务端.py
               3 个文件          1,509 字节
               3 个目录 217,707,405,312 可用字节

to client success

客户端接收到的结果:

cmd>>:tasklist
>>
映像名称                       PID 会话名              会话#       内存使用 
========================= ======== ================ =========== ============
System Idle Process              0 Services                   0          8 K
System                           4 Services                   0     27,848 K
Registry                        96 Services                   0     41,200 K
smss.exe                       360 Services                   0        924 K
csrss.exe                      600 Services                   0      5,272 K
wininit.exe                    700 Services                   0      6,332 K
csrss.exe                      728                            1      4,888 K
services.exe                   776 Services                   0      8,612 K
lsass.exe                      848 Services                   0     21,060 K
svchost.exe                    984 Services                   0      3,596 K
fontdrvhost.exe               1008 Services                   0      3,048 K
svchost.
cmd>>:dir
>>exe                    560 Services                   0     31,540 K
svchost.exe                    556 Services                   0     14,772 K
svchost.exe                    868 Services                   0      7,908 K
svchost.exe                   1204 Services                   0     10,228 K
svchost.exe                   1292 Services                   0     11,932 K
svchost.exe                   1408 Services                   0     15,228 K
svchost.exe                   1420 Services                   0     14,044 K
svchost.exe                   1448 Services                   0      6,972 K
svchost.exe                   1480 Services                   0      5,564 K
svchost.exe                   1540 Services                   0     10,392 K
svchost.exe                   1676 Services                   0      9,800 K
svchost.exe                   1732 Services                   0     10,412 K
svchost.exe                   1744 Services                   0      7,556 K
svchost.exe       
cmd>>:

2、struct模块

2.1 介绍

headers = struct.pack('i',length)

参数为i的时候,将一个整形数字length通过某个规则转化为一个4字节长度的bytes数据,应用在数据传输时,可以将数据流的长度传入,转化为header

struct.unpack('i',headers)

参数为i的时候,将一个struct.pack('i',length)得到的4个字节长度的bytes类型数据headers,还原为header被压缩之前的整形数值length,是一个元组(length,)

演示:

import struct
headers_by_pack = struct.pack('i',100)
print(f'headers_by_pack:{headers_by_pack}')
headers_by_unpack = struct.unpack('i',headers_by_pack)
print(f'headers_by_unpack:{headers_by_unpack}')

'''
headers_by_pack:b'd\x00\x00\x00'
headers_by_unpack:(100,)'''

2.2 利用struct模块解决粘包问题

# 客户端.py
import socket
import struct

client = socket.socket()
client.connect(('127.0.0.1',10086))
while True:
    cmd = input('cmd>>:').encode('utf8')
    client.send(cmd)

    headers = client.recv(4)  # 接收报头headers,包头信息固定为4个字节,所以用4个字节就能接收到全部的报头数据
    result_len = struct.unpack('i',headers)[0]  # 获取报头内容,里面包含了将要接收的数据真正的数据流长度

    result = client.recv(result_len).decode('gbk')  # 设定最大接收数据流长度为报头中得到的数据,即真正的将要接收的数据流长度,这样就能接收到全部的数据了
    print(f'>>{result}')
    if result == 'q':
        break
# 服务端.py
# 服务器.py
import socket
import subprocess
import struct

server = socket.socket()
server.bind(('127.0.0.1', 10086))
server.listen(5)

while True:
    conn, addr = server.accept()  # 链接客户端
    print(f'{addr}:')
    while True:
        try:
            cmd = conn.recv(1024).decode('utf8')
            print(f'from client:{cmd}')
            if cmd == 'q':
                conn.send(cmd.encode('utf8'))
                break

            # 1 subprocess.Popen()
            obj = subprocess.Popen(
                cmd,
                shell=True,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE
            )
            restult = obj.stdout.read() + obj.stderr.read()  # 真正的bytes类型执行结果
            print(restult.decode('gbk'))

            len_data = len(restult)  # 真正的bytes类型数据字节数,即长度
            headers = struct.pack('i',len_data)  # 将真正的bytes数据字节长度按格式'i'压缩成4个字节,即得到报头
            conn.send(headers)  # 先将报头发送给客户端,告知将要发送的数据的信息,其中包含数据流长度,即bytes数据字节数

            conn.send(restult)  # 发送真正的bytes数据流
            print('to client success')
        except Exception as e:
            print(f'e:{e}')
            break
    conn.close()  # 执行命令出错或者与该客户端的链接已断开

2.2 实例:上传大文件

# 服务端.py
import socket
import json
import struct

server = socket.socket()
server.bind(('127.0.0.1', 10086))
server.listen()
while True:
    conn, addr = server.accept()
    print(f'客户端:{addr}')

    info_headers = conn.recv(4)
    len_of_info_headers = struct.unpack('i', info_headers)[0]

    file_info_json = conn.recv(len_of_info_headers).decode('utf-8')
    file_info = json.loads(file_info_json)

    file_name, file_length = file_info.values()  # 字典解压缩时,取值顺序?
    file_data = conn.recv(file_length)  # 视频文件不需解码
    print('接收完成')

    # 存储文件
    with open(file_name, 'wb') as fw:
        fw.write(file_data)
    print(f'存储成功')

# 客户端.py
import socket
import json
import struct
import os

client = socket.socket()
client.connect(('127.0.0.1', 10086))

while True:
    file_path = r'C:\Users\Administrator\Desktop\day27code\3 上传大文件\jason真实写真集.mp4'
    file_name = os.path.basename(file_path)

    print(f'将要上传文件{file_name}')
    choice = input('''
    1   开始上传
    q   退出''')
    if choice == 'q':
        break
    if choice != '1':
        print('请选择1或q')
        continue

    # 打开文件,获取文件大小
    with open(file_path, 'rb') as fr:
        movie_bytes = fr.read()

    # 先将带有文件信息的字典json串发送到服务端,告诉服务端将要接收的数据的信息
    file_info = {'file_name': file_name, 'file_size': len(movie_bytes)}
    file_info_json = json.dumps(file_info)

    bytes_info = file_info_json.encode('utf-8')
    headers1 = struct.pack('i', len(bytes_info))
    client.send(headers1)
    client.send(bytes_info)

    # 发送真正的数据movie_bytes
    # client.send(movie_bytes)
    # print('上传成功')

    # 也可以采用多次发送,读文件时,读取一部分就上传一部分
    size = 0
    num = 1
    with open(file_path, 'rb') as fr:
        while size < len(movie_bytes):
            data = fr.read(1024)
            client.send(data)
            print(num, f'已上传{len(data)}bytes')
            size += len(data)
            num += 1
            print(size,len(movie_bytes))  # 为何读取完成之后,size才只有movie_bytes的一半
    print('上传成功')

posted @ 2019-10-20 22:56  W文敏W  阅读(169)  评论(0编辑  收藏  举报