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最大接收字节数,没有接收完,还遗留在管道里,就出现了粘包现象

  • 相关阅读:
    Tabindex
    bootStrap下拉菜单 点击下拉列表某个元素,列表不隐藏
    ionic--分模块
    ionic--配置路由
    ionic —指令
    一个简单的Makefile的编写【用自己的话,解释清楚这些】
    使用ptrace向已运行进程中注入.so并执行相关函数
    StrictMode模式介绍
    adb server is out of date. killing...
    交叉编译lsof for android
  • 原文地址:https://www.cnblogs.com/xudachen/p/8735270.html
Copyright © 2011-2022 走看看