zoukankan      html  css  js  c++  java
  • Python--网络编程-----粘包现象

    一、为了防止出现端口占用的情况,

    linux中可以使用pkill -9 python

    windows系统中使用taskkill python

    二、什么是粘包现象

    1、多个包(也就是多个命令的执行结果)粘在一起的现象,叫做粘包现象

    2、代码示例如下:

    服务端代码:

     1 import socket
     2 import subprocess
     3 
     4 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     5 # phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
     6 phone.bind(('127.0.0.1', 9081))  # 0-65535:0-1024给操作系统使用
     7 phone.listen(5)
     8 
     9 print('starting......')
    10 while True:  # 链接循环
    11     conn, client_addr = phone.accept()
    12     print(client_addr)
    13 
    14     while True:  # 通信循环
    15         try:
    16             # 1、收命令
    17             cmd = conn.recv(1024)
    18             if not cmd:  # 适用于linux操作系统
    19                 break
    20             print('客户端的数据', cmd)
    21 
    22             # 2、执行命令,拿到结果
    23             obj = subprocess.Popen(cmd.decode('utf-8'), shell=True,
    24                                    stdout=subprocess.PIPE,
    25                                    stderr=subprocess.PIPE)
    26 
    27             stdout = obj.stdout.read()
    28             stderr = obj.stderr.read()
    29             # 3、把命令的结果返回给客户端
    30             print(len(stdout) + len(stderr))
    31             conn.send(stdout+stderr)
    32 
    33         except ConnectionResetError:  # 适用于Windows操作系统
    34             break
    35 
    36     conn.close()
    37 
    38 phone.close()

    客户端代码:

     1 import socket
     2 
     3 
     4 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     5 
     6 phone.connect(('127.0.0.1', 9081))
     7 
     8 while True:
     9     # 1、发命令
    10     cmd = input('>>:').strip()
    11     if not cmd:
    12         continue
    13     phone.send(cmd.encode('utf-8'))
    14 
    15     # 2、拿命令的结果,打印
    16     data = phone.recv(1024)
    17     print(data.decode('gbk'))
    18 
    19 phone.close()

    在客户端依次输入dir,ipconfig,dir,

    客户端运行结果为:

     1 C:Usersxu516PycharmProjectsPython全栈开发venvScriptspython.exe "C:/Users/xu516/PycharmProjects/Python全栈开发/第三模块/网络编程/04 粘包现象/客户端.py"
     2 >>:dir
     3  驱动器 C 中的卷是 OS
     4  卷的序列号是 7849-BAF9
     5 
     6  C:Usersxu516PycharmProjectsPython全栈开发第三模块网络编程4 粘包现象 的目录
     7 
     8 2018/04/07  22:17    <DIR>          .
     9 2018/04/07  22:17    <DIR>          ..
    10 2018/04/05  21:18                 0 __init__.py
    11 2018/04/07  22:17               376 客户端.py
    12 2018/04/07  22:17             1,194 服务端.py
    13                3 个文件          1,570 字节
    14                2 个目录 36,304,265,216 可用字节
    15 
    16 >>:ipconfig
    17 
    18 Windows IP 配置
    19 
    20 
    21 无线局域网适配器 本地连接* 3:
    22 
    23    媒体状态  . . . . . . . . . . . . : 媒体已断开连接
    24    连接特定的 DNS 后缀 . . . . . . . : 
    25 
    26 以太网适配器 VMware Network Adapter VMnet1:
    27 
    28    连接特定的 DNS 后缀 . . . . . . . : 
    29    本地链接 IPv6 地址. . . . . . . . : fe80::5d54:4c1:d7d6:c647%6
    30    IPv4 地址 . . . . . . . . . . . . : 192.168.189.1
    31    子网掩码  . . . . . . . . . . . . : 255.255.255.0
    32    默认网关. . . . . . . . . . . . . : 
    33 
    34 以太网适配器 VMware Network Adapter VMnet8:
    35 
    36    连接特定的 DNS 后缀 . . . . . . . : 
    37    本地链接 IPv6 地址. . . . . . . . : fe80::680e:7f79:aed1:fe62%10
    38    IPv4 地址 . . . . . . . . . . . . : 192.168.254.1
    39    子网掩码  . . . . . . . . . . . . : 255.255.255.0
    40    默认网关. . . . . . . . . . . . . : 
    41 
    42 无线局域网适配器 WLAN:
    43 
    44    连接特定的 DNS 后缀 . . . . . . . : DHCP HOST
    45    本地链接 IPv6 地址. . . . . . . . : fe80::9c84:419c:e3af:89dd%11
    46    IPv4 地址 . . . . . . . . . . . . : 192.168.0.106
    47    子网掩码  . . . . . . . . . . . . : 255.255.255.0
    48    
    49 >>:dir
    50 默认网关. . . . . . . . . . . . . : 192.168.0.1
    51 
    52 以太网适配器 蓝牙网络连接:
    53 
    54    媒体状态  . . . . . . . . . . . . : 媒体已断开连接
    55    连接特定的 DNS 后缀 . . . . . . . : 
    56 
    57 隧道适配器 Teredo Tunneling Pseudo-Interface:
    58 
    59    连接特定的 DNS 后缀 . . . . . . . : 
    60    IPv6 地址 . . . . . . . . . . . . : 2001:0:9d38:953c:20d3:83ef:d86a:f024
    61    本地链接 IPv6 地址. . . . . . . . : fe80::20d3:83ef:d86a:f024%2
    62    默认网关. . . . . . . . . . . . . : ::
    63 
    64 >>:

    第一次输入dir显示结果正常,第二次输入dir输出结果却为ip地址信息,也就是上一个ifconfig命令的遗留信息,这种现象就叫做粘包现象,

    代码中服务端和客户端recv指定的最大接收字节数都为1024个字节,我们可以在服务端上看看命令执行结果的长度,如下:

    1 starting......
    2 ('127.0.0.1', 60296)
    3 客户端的数据 b'dir'
    4 453
    5 客户端的数据 b'ipconfig'
    6 1481
    7 客户端的数据 b'dir'
    8 453

    可以看出,ipconfig命令结果的长度超出了recv最大接收字节数,没有接收完,还遗留在管道里,就出现了粘包现象

  • 相关阅读:
    1144 The Missing Number (20分)
    1145 Hashing
    1146 Topological Order (25分)
    1147 Heaps (30分)
    1148 Werewolf
    1149 Dangerous Goods Packaging (25分)
    TypeReference
    Supervisor安装与配置()二
    谷粒商城ES调用(十九)
    Found interface org.elasticsearch.common.bytes.BytesReference, but class was expected
  • 原文地址:https://www.cnblogs.com/xudachen/p/8735270.html
Copyright © 2011-2022 走看看