16 [网络编程]-粘包

1、粘包

 粘包,就是指两次结果粘到一起了。它的发生主要是因为socket缓冲区导致的,来看一下

 

你的程序实际上无权直接操作网卡的,你操作网卡都是通过操作系统给用户程序暴露出来的接口,
那每次你的程序要给远程发数据时,其实是先把数据从用户态copy到内核态,
这样的操作是耗资源和时间的,频繁的在内核态和用户态之前交换数据势必会导致发送效率降低,
 因此socket 为提高传输效率,发送方往往要收集到足够多的数据后才发送一次数据给对方。
若连续几次需要send的数据都很少,
通常TCP socket 会根据优化算法把这些数据合成一个TCP段后一次发送出去,
这样接收方就收到了粘包数据。

  

 

2、粘包问题只存在于TCP中,Not UDP

  •  TCP协议是面向流的协议
还是看上图,发送端可以是一K一K地发送数据,
而接收端的应用程序可以两K两K地提走数据,当然也有可能一次提走3K或6K数据,或者一次只提走几个字节的数据,
也就是说,应用程序所看到的数据是一个整体,或说是一个流(stream),一条消息有多少字节对应用程序是不可见的,
因此TCP协议是面向流的协议,这也是容易出现粘包问题的原因
  • UDP是面向消息的协议
UDP是面向消息的协议,每个UDP段都是一条消息,应用程序必须以消息为单位提取数据,不能一次提取任意字节的数据,
这一点和TCP是很不同的。怎样定义消息呢?可以认为对方一次性write/send的数据为一个消息,需要明白的是当对方send一条信息的时候,
无论底层怎样分段分片,TCP协议层会把构成整条消息的数据段排序完成后才呈现在内核缓冲区。

  

总结

  1. TCP(transport control protocol,传输控制协议)是面向连接的,面向流的,提供高可靠性服务。收发两端(客户端和服务器端)都要有一一成对的socket,因此,发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小且数据量小的数据,合并成一个大的数据块,然后进行封包。这样,接收端,就难于分辨出来了,必须提供科学的拆包机制。 即面向流的通信是无消息保护边界的。
  2. UDP(user datagram protocol,用户数据报协议)是无连接的,面向消息的,提供高效率服务。不会使用块的合并优化算法,, 由于UDP支持的是一对多的模式,所以接收端的skbuff(套接字缓冲区)采用了链式结构来记录每一个到达的UDP包,在每个UDP包中就有了消息头(消息来源地址,端口等信息),这样,对于接收端来说,就容易进行区分处理了。 即面向消息的通信是有消息保护边界的。
  3. tcp是基于数据流的,于是收发的消息不能为空,这就需要在客户端和服务端都添加空消息的处理机制,防止程序卡住,而udp是基于数据报的,即便是你输入的是空内容(直接回车),那也不是空消息,udp协议会帮你封装上消息头,实验略

 

3、send与recv的区别

 

 

4、粘包现象

  • 两次send:数据量小,时间间隔很短,会发生粘包

  (1)服务端

# 两次send:数据量小,时间间隔很短,会发生粘包

import socket
import time
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', 9999))
server.listen(5)

print('... waiting...')
conn, addr = server.accept()

#data1 = conn.recv(1024)

data1 = conn.recv(1)  # 当只取一个字符的时候,剩下的数据还在缓存池里面,下次会继续取出来
print('第一次', data1)

data2 = conn.recv(1024)
print('第二次', data2)

conn.close()
server.close()

 

  

  (2)客户端

# 两次send:数据量小,时间间隔很短,会发生粘包

import socket
import time

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', 9999))

client.send('hello'.encode('utf-8'))

# time.sleep(1)  两次send直接隔一段时间,不会发生粘包现象

client.send('world'.encode('utf-8'))

client.close()

  

 

5、解决粘包问题:普通版

问题的根源在于,接收端不知道发送端将要传送的字节流的长度,所以解决粘包的方法就是围绕,如何让发送端在发送数据前,把自己将要发送的字节流总大小让接收端知晓,

然后接收端来一个死循环接收完所有数据

 (1)服务端

import socket
import subprocess

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

server.bind(('127.0.0.1', 9994))

server.listen(5)

while True:
    print('waiting...')
    conn, addr = server.accept()

    while True:
        try:
            data = conn.recv(1024)
            print('=》', data)
            if not data:
                break

            obj = subprocess.Popen(data.decode('utf-8'), shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   )

            # 3.把取出命令的结果
            stdout = obj.stdout.read()
            stderr = obj.stderr.read()

            # 3.1 把数据的长度发送给客户端
            total_size = len(stdout+stderr)
            conn.send(str(total_size).encode('utf-8'))

            # 3.2 在发送真实的数据
            conn.send(stdout)   # 粘包可以
            conn.send(stderr)

        except ConnectionResetError:
            break

    conn.close()


server.close()

 

  

  (2)客户端

import socket

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

client.connect(('127.0.0.1', 9994))

while True:

    data = input('>>>').strip()         # 粘包现象,当输入ipconfig的时候,缓存池会存放太多的结果
    if not data:
        continue
    client.send(data.encode('utf-8'))

    # 2.接受数据的长度
    total_size = client.recv(1024)

    # 3.取出报文的长度
    total_size = int(total_size.decode('utf-8'))

    # 3.一段段的取数据
    total_data = b''
    recv_size = 0

    while recv_size < total_size:  # 接受的数据长度 = len(total_data) 已经取完了,就退出
        data = client.recv(1024)
        total_data += data
        recv_size += len(data)

    print(total_data.decode('gbk'))

client.close()

 

C:\Python34\python.exe C:/PycharmProjects/Luffy_project/Luffy-网络编程/07-解决粘包问题/03-客户端.py
>>>dir
 驱动器 C 中的卷没有标签。
 卷的序列号是 E08A-FCF5

 C:\PycharmProjects\Luffy_project\Luffy-网络编程\07-解决粘包问题 的目录

2018/03/28 周三  下午 08:27    <DIR>          .
2018/03/28 周三  下午 08:27    <DIR>          ..
2018/03/28 周三  下午 08:10             1,114 02-服务端2.py
2018/03/28 周三  下午 08:27               818 03-客户端.py
               2 个文件          1,932 字节
               2 个目录 124,168,138,752 可用字节

>>>
>>>ipconfig

Windows IP 配置


无线局域网适配器 无线网络连接 5:

   连接特定的 DNS 后缀 . . . . . . . : 
   本地链接 IPv6 地址. . . . . . . . : fe80::7512:dae3:9ef5:f6d3%19
   IPv4 地址 . . . . . . . . . . . . : 192.168.191.1
   子网掩码  . . . . . . . . . . . . : 255.255.255.0
   默认网关. . . . . . . . . . . . . : 

无线局域网适配器 无线网络连接:

   媒体状态  . . . . . . . . . . . . : 媒体已断开
   连接特定的 DNS 后缀 . . . . . . . : 

以太网适配器 本地连接:

   连接特定的 DNS 后缀 . . . . . . . : 
   IPv6 地址 . . . . . . . . . . . . : 2001:da8:4015:a:2060:b9c5:9ddb:1343
   临时 IPv6 地址. . . . . . . . . . : 2001:da8:4015:a:65c2:fdc:ae01:f622
   本地链接 IPv6 地址. . . . . . . . : fe80::2060:b9c5:9ddb:1343%12
   IPv4 地址 . . . . . . . . . . . . : 10.8.6.11
   子网掩码  . . . . . . . . . . . . : 255.255.254.0
   默认网关. . . . . . . . . . . . . : fe80::3ee5:a6ff:fe6c:98c1%12
                                       10.8.7.254

以太网适配器 VMware Network Adapter VMnet1:

   连接特定的 DNS 后缀 . . . . . . . : 
   本地链接 IPv6 地址. . . . . . . . : fe80::91c:c41:5755:bd67%14
   IPv4 地址 . . . . . . . . . . . . : 192.168.48.1
   子网掩码  . . . . . . . . . . . . : 255.255.255.0
   默认网关. . . . . . . . . . . . . : 

以太网适配器 VMware Network Adapter VMnet8:

   连接特定的 DNS 后缀 . . . . . . . : 
   本地链接 IPv6 地址. . . . . . . . : fe80::4cfa:7057:d006:cbf0%15
   IPv4 地址 . . . . . . . . . . . . : 192.168.28.1
   子网掩码  . . . . . . . . . . . . : 255.255.255.0
   默认网关. . . . . . . . . . . . . : 

隧道适配器 isatap.{D0793028-C9C4-44BD-84A9-7ACFE0D6D454}:

   媒体状态  . . . . . . . . . . . . : 媒体已断开
   连接特定的 DNS 后缀 . . . . . . . : 

隧道适配器 本地连接*:

   媒体状态  . . . . . . . . . . . . : 媒体已断开
   连接特定的 DNS 后缀 . . . . . . . : 

隧道适配器 isatap.{592418B3-F47A-489C-A9E5-1EDEC7B499C1}:

   媒体状态  . . . . . . . . . . . . : 媒体已断开
   连接特定的 DNS 后缀 . . . . . . . : 

隧道适配器 isatap.{D8C47ABB-48E9-4B35-BE81-29A998780E04}:

   媒体状态  . . . . . . . . . . . . : 媒体已断开
   连接特定的 DNS 后缀 . . . . . . . : 

隧道适配器 isatap.{F30B37DD-15CE-4B19-8B0F-BF1495C3081D}:

   媒体状态  . . . . . . . . . . . . : 媒体已断开
   连接特定的 DNS 后缀 . . . . . . . : 

隧道适配器 isatap.{1A8AE88C-5BF7-4219-B60F-72E3ACF6FF35}:

   媒体状态  . . . . . . . . . . . . : 媒体已断开
   连接特定的 DNS 后缀 . . . . . . . : 

隧道适配器 6TO4 Adapter:

   媒体状态  . . . . . . . . . . . . : 媒体已断开
   连接特定的 DNS 后缀 . . . . . . . : 

>>>
>>>dir
 驱动器 C 中的卷没有标签。
 卷的序列号是 E08A-FCF5

 C:\PycharmProjects\Luffy_project\Luffy-网络编程\07-解决粘包问题 的目录

2018/03/28 周三  下午 08:27    <DIR>          .
2018/03/28 周三  下午 08:27    <DIR>          ..
2018/03/28 周三  下午 08:10             1,114 02-服务端2.py
2018/03/28 周三  下午 08:27               818 03-客户端.py
               2 个文件          1,932 字节
               2 个目录 124,168,138,752 可用字节

>>>
运行结果

 

6、解决粘包问题:struct模块

  • 为字节流加上自定义固定长度报头也可以借助于第三方模块struc
import struct

# 为字节流加上自定义固定长度报头 4个 bytes
data = 'alex123'
ret = struct.pack('i', len(data))    # i 模式
print(ret,ret.decode('utf-8'), len(ret), type(ret)) # b'\x07\x00\x00\x00'     4 <class 'bytes'>


obj = struct.unpack('i', ret)
print(obj)   # (10,)
data_len = obj[0]
print(data_len)     # 数据长度 7 个

 

 

  (1)服务端

import socket
import struct
import subprocess


server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

server.bind(('127.0.0.1', 9994))

server.listen(5)

while True:
    print('waiting...')
    conn, addr = server.accept()

    while True:
        try:
            data = conn.recv(1024)
            print('=》', data)
            if not data:
                break

            obj = subprocess.Popen(data.decode('utf-8'), shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   )

            # 3.把取出命令的结果
            stdout = obj.stdout.read()
            stderr = obj.stderr.read()

            # 3.1 把数据的长度发送给客户端
            # 第一步:制作固定长度的报头
            total_size = len(stdout + stderr)
            ret = struct.pack('i',total_size)  # bytes格式

            # 第二部:把报头发送给客户端
            conn.send(ret)

            # 第三部:发送真实数据
            conn.send(stdout)   # 粘包可以
            conn.send(stderr)

        except ConnectionResetError:
            break

    conn.close()


server.close()

 

  

  (2)客户端

import socket
import struct

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

client.connect(('127.0.0.1', 9994))

while True:

    data = input('>>>').strip()         # 粘包现象,当输入ipconfig的时候,缓存池会存放太多的结果
    if not data:
        continue
    client.send(data.encode('utf-8'))

    # 2.接受报头
    ret = client.recv(1024)

    # 3.从报头中解析出对真实数据的描述信息(数据的长度)
    obj = struct.unpack('i',ret)
    total_size = obj[0]

    # 3.一段段的取数据
    total_data = b''
    recv_size = 0

    while recv_size < total_size:  # 接受的数据长度 = len(total_data) 已经取完了,就退出
        data = client.recv(1024)
        total_data += data
        recv_size += len(data)

    print(total_data.decode('gbk'))

client.close()

 

 

C:\Python34\python.exe C:/PycharmProjects/Luffy_project/Luffy-网络编程/08-粘包-struct模块/03-客户端.py
>>>ipconfig

Windows IP 配置


无线局域网适配器 无线网络连接 5:

   连接特定的 DNS 后缀 . . . . . . . : 
   本地链接 IPv6 地址. . . . . . . . : fe80::7512:dae3:9ef5:f6d3%19
   IPv4 地址 . . . . . . . . . . . . : 192.168.191.1
   子网掩码  . . . . . . . . . . . . : 255.255.255.0
   默认网关. . . . . . . . . . . . . : 

无线局域网适配器 无线网络连接:

   媒体状态  . . . . . . . . . . . . : 媒体已断开
   连接特定的 DNS 后缀 . . . . . . . : 

以太网适配器 本地连接:

   连接特定的 DNS 后缀 . . . . . . . : 
   IPv6 地址 . . . . . . . . . . . . : 2001:da8:4015:a:2060:b9c5:9ddb:1343
   临时 IPv6 地址. . . . . . . . . . : 2001:da8:4015:a:65c2:fdc:ae01:f622
   本地链接 IPv6 地址. . . . . . . . : fe80::2060:b9c5:9ddb:1343%12
   IPv4 地址 . . . . . . . . . . . . : 10.8.6.11
   子网掩码  . . . . . . . . . . . . : 255.255.254.0
   默认网关. . . . . . . . . . . . . : fe80::3ee5:a6ff:fe6c:98c1%12
                                       10.8.7.254

以太网适配器 VMware Network Adapter VMnet1:

   连接特定的 DNS 后缀 . . . . . . . : 
   本地链接 IPv6 地址. . . . . . . . : fe80::91c:c41:5755:bd67%14
   IPv4 地址 . . . . . . . . . . . . : 192.168.48.1
   子网掩码  . . . . . . . . . . . . : 255.255.255.0
   默认网关. . . . . . . . . . . . . : 

以太网适配器 VMware Network Adapter VMnet8:

   连接特定的 DNS 后缀 . . . . . . . : 
   本地链接 IPv6 地址. . . . . . . . : fe80::4cfa:7057:d006:cbf0%15
   IPv4 地址 . . . . . . . . . . . . : 192.168.28.1
   子网掩码  . . . . . . . . . . . . : 255.255.255.0
   默认网关. . . . . . . . . . . . . : 

隧道适配器 isatap.{D0793028-C9C4-44BD-84A9-7ACFE0D6D454}:

   媒体状态  . . . . . . . . . . . . : 媒体已断开
   连接特定的 DNS 后缀 . . . . . . . : 

隧道适配器 本地连接*:

   媒体状态  . . . . . . . . . . . . : 媒体已断开
   连接特定的 DNS 后缀 . . . . . . . : 

隧道适配器 isatap.{592418B3-F47A-489C-A9E5-1EDEC7B499C1}:

   媒体状态  . . . . . . . . . . . . : 媒体已断开
   连接特定的 DNS 后缀 . . . . . . . : 

隧道适配器 isatap.{D8C47ABB-48E9-4B35-BE81-29A998780E04}:

   媒体状态  . . . . . . . . . . . . : 媒体已断开
   连接特定的 DNS 后缀 . . . . . . . : 

隧道适配器 isatap.{F30B37DD-15CE-4B19-8B0F-BF1495C3081D}:

   媒体状态  . . . . . . . . . . . . : 媒体已断开
   连接特定的 DNS 后缀 . . . . . . . : 

隧道适配器 isatap.{1A8AE88C-5BF7-4219-B60F-72E3ACF6FF35}:

   媒体状态  . . . . . . . . . . . . : 媒体已断开
   连接特定的 DNS 后缀 . . . . . . . : 

隧道适配器 6TO4 Adapter:

   媒体状态  . . . . . . . . . . . . : 媒体已断开
   连接特定的 DNS 后缀 . . . . . . . : 

>>>dir
 驱动器 C 中的卷没有标签。
 卷的序列号是 E08A-FCF5

 C:\PycharmProjects\Luffy_project\Luffy-网络编程\08-粘包-struct模块 的目录

2018/03/28 周三  下午 10:30    <DIR>          .
2018/03/28 周三  下午 10:30    <DIR>          ..
2018/03/28 周三  下午 09:09               360 01-struct.py
2018/03/28 周三  下午 09:10             1,281 02-服务端2.py
2018/03/28 周三  下午 09:13               877 03-客户端.py
2018/03/28 周三  下午 09:15               436 04-struct超出.py
2018/03/28 周三  下午 09:39               902 05-标准数据报头格式.py
2018/03/28 周三  下午 10:30             1,738 06-服务端2.py
2018/03/28 周三  下午 10:30             1,222 07-客户端.py
               7 个文件          6,816 字节
               2 个目录 124,167,741,440 可用字节

>>>
运行结果

 

 

7、数据长度超出struct的标准

 

8、制作标准报头

 

9、解决粘包问题:json struct

import json,struct
#假设通过客户端上传1T:1073741824000的文件a.txt

#为避免粘包,必须自定制报头
header={'file_size':1073741824000,'file_name':'/a/b/c/d/e/a.txt','md5':'8f6fbf8347faa4924a76856701edb0f3'} #1T数据,文件路径和md5值

#为了该报头能传送,需要序列化并且转为bytes
head_bytes=bytes(json.dumps(header),encoding='utf-8') #序列化并转成bytes,用于传输

#为了让客户端知道报头的长度,用struck将报头长度这个数字转成固定长度:4个字节
head_len_bytes=struct.pack('i',len(head_bytes)) #这4个字节里只包含了一个数字,该数字是报头的长度

#客户端开始发送
conn.send(head_len_bytes) #先发报头的长度,4个bytes
conn.send(head_bytes) #再发报头的字节格式
conn.sendall(文件内容) #然后发真实内容的字节格式

#服务端开始接收
head_len_bytes=s.recv(4) #先收报头4个bytes,得到报头长度的字节格式
x=struct.unpack('i',head_len_bytes)[0] #提取报头的长度

head_bytes=s.recv(x) #按照报头长度x,收取报头的bytes格式
header=json.loads(json.dumps(header)) #提取报头

#最后根据报头的内容提取真实的数据,比如
real_data_len=s.recv(header['file_size'])
s.recv(real_data_len)

  

  (1)服务端

import socket
import struct
import subprocess
import json


server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

server.bind(('127.0.0.1', 9994))

server.listen(5)

while True:
    print('waiting...')
    conn, addr = server.accept()

    while True:
        try:
            data = conn.recv(1024)
            print('=》', data)
            if not data:
                break

            obj = subprocess.Popen(data.decode('utf-8'), shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE,
                                   )

            # 3.把取出命令的结果
            stdout = obj.stdout.read()
            stderr = obj.stderr.read()

            # 3.1 把数据的长度发送给客户端
            # 第一步:制作报头
            total_size = len(stdout + stderr)
            header_dict = {
                'filename': 'a.txt',
                'md5': 'afdsafsaf',
                'total_size': total_size
            }
            header_json = json.dumps(header_dict)  # 报头的json样式
            header_bytes = header_json.encode('utf-8')          # 报头---报头.json---报头.bytes

            # 发送报头的长度
            header_len = struct.pack('i', len(header_bytes))    # 报头bytes---> len()---> struct
            conn.send(header_len)

            # 第二部:把报头发送给客户端
            conn.send(header_bytes)

            # 第三部:发送真实数据
            conn.send(stdout)   # 粘包可以
            conn.send(stderr)

        except ConnectionResetError:
            break

    conn.close()


server.close()

 

 

  (2)客户端

import socket
import struct
import json

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

client.connect(('127.0.0.1', 9994))

while True:

    data = input('>>>').strip()         # 粘包现象,当输入ipconfig的时候,缓存池会存放太多的结果
    if not data:
        continue
    client.send(data.encode('utf-8'))

    # 2.接受报头的长度         4 个bytes----》struct----》 header_bytes的len
    header_bytes_len = client.recv(1024)
    header_bytes_len = struct.unpack('i', header_bytes_len)[0]

    # 接收报头的json数据
    header_bytes = client.recv(header_bytes_len)
    print(header_bytes)

    # 3.从报头中解析出对真实数据的描述信息(数据的长度)
    header_json = header_bytes.decode('utf-8')
    header_dict = json.loads(header_json)

    total_size = header_dict['total_size']

    # 3.一段段的取数据
    total_data = b''
    recv_size = 0

    while recv_size < total_size:  # 接受的数据长度 = len(total_data) 已经取完了,就退出
        data = client.recv(1024)
        total_data += data
        recv_size += len(data)

    print(total_data.decode('gbk'))

client.close()

 

 

C:\Python34\python.exe C:/PycharmProjects/Luffy_project/Luffy-网络编程/08-粘包-struct模块/07-客户端.py
>>>ipconfig
b'{"total_size": 2587, "md5": "afdsafsaf", "filename": "a.txt"}'

Windows IP 配置


无线局域网适配器 无线网络连接 5:

   连接特定的 DNS 后缀 . . . . . . . : 
   本地链接 IPv6 地址. . . . . . . . : fe80::7512:dae3:9ef5:f6d3%19
   IPv4 地址 . . . . . . . . . . . . : 192.168.191.1
   子网掩码  . . . . . . . . . . . . : 255.255.255.0
   默认网关. . . . . . . . . . . . . : 

无线局域网适配器 无线网络连接:

   媒体状态  . . . . . . . . . . . . : 媒体已断开
   连接特定的 DNS 后缀 . . . . . . . : 

以太网适配器 本地连接:

   连接特定的 DNS 后缀 . . . . . . . : 
   IPv6 地址 . . . . . . . . . . . . : 2001:da8:4015:a:2060:b9c5:9ddb:1343
   临时 IPv6 地址. . . . . . . . . . : 2001:da8:4015:a:65c2:fdc:ae01:f622
   本地链接 IPv6 地址. . . . . . . . : fe80::2060:b9c5:9ddb:1343%12
   IPv4 地址 . . . . . . . . . . . . : 10.8.6.11
   子网掩码  . . . . . . . . . . . . : 255.255.254.0
   默认网关. . . . . . . . . . . . . : fe80::3ee5:a6ff:fe6c:98c1%12
                                       10.8.7.254

以太网适配器 VMware Network Adapter VMnet1:

   连接特定的 DNS 后缀 . . . . . . . : 
   本地链接 IPv6 地址. . . . . . . . : fe80::91c:c41:5755:bd67%14
   IPv4 地址 . . . . . . . . . . . . : 192.168.48.1
   子网掩码  . . . . . . . . . . . . : 255.255.255.0
   默认网关. . . . . . . . . . . . . : 

以太网适配器 VMware Network Adapter VMnet8:

   连接特定的 DNS 后缀 . . . . . . . : 
   本地链接 IPv6 地址. . . . . . . . : fe80::4cfa:7057:d006:cbf0%15
   IPv4 地址 . . . . . . . . . . . . : 192.168.28.1
   子网掩码  . . . . . . . . . . . . : 255.255.255.0
   默认网关. . . . . . . . . . . . . : 

隧道适配器 isatap.{D0793028-C9C4-44BD-84A9-7ACFE0D6D454}:

   媒体状态  . . . . . . . . . . . . : 媒体已断开
   连接特定的 DNS 后缀 . . . . . . . : 

隧道适配器 本地连接*:

   媒体状态  . . . . . . . . . . . . : 媒体已断开
   连接特定的 DNS 后缀 . . . . . . . : 

隧道适配器 isatap.{592418B3-F47A-489C-A9E5-1EDEC7B499C1}:

   媒体状态  . . . . . . . . . . . . : 媒体已断开
   连接特定的 DNS 后缀 . . . . . . . : 

隧道适配器 isatap.{D8C47ABB-48E9-4B35-BE81-29A998780E04}:

   媒体状态  . . . . . . . . . . . . : 媒体已断开
   连接特定的 DNS 后缀 . . . . . . . : 

隧道适配器 isatap.{F30B37DD-15CE-4B19-8B0F-BF1495C3081D}:

   媒体状态  . . . . . . . . . . . . : 媒体已断开
   连接特定的 DNS 后缀 . . . . . . . : 

隧道适配器 isatap.{1A8AE88C-5BF7-4219-B60F-72E3ACF6FF35}:

   媒体状态  . . . . . . . . . . . . : 媒体已断开
   连接特定的 DNS 后缀 . . . . . . . : 

隧道适配器 6TO4 Adapter:

   媒体状态  . . . . . . . . . . . . : 媒体已断开
   连接特定的 DNS 后缀 . . . . . . . : 

>>>dir
b'{"total_size": 763, "md5": "afdsafsaf", "filename": "a.txt"}'
 驱动器 C 中的卷没有标签。
 卷的序列号是 E08A-FCF5

 C:\PycharmProjects\Luffy_project\Luffy-网络编程\08-粘包-struct模块 的目录

2018/03/30 周五  下午 11:52    <DIR>          .
2018/03/30 周五  下午 11:52    <DIR>          ..
2018/03/28 周三  下午 09:09               360 01-struct.py
2018/03/28 周三  下午 09:10             1,281 02-服务端2.py
2018/03/28 周三  下午 09:13               877 03-客户端.py
2018/03/30 周五  下午 11:52               436 04-struct超出.py
2018/03/28 周三  下午 09:39               902 05-标准数据报头格式.py
2018/03/28 周三  下午 10:30             1,738 06-服务端2.py
2018/03/28 周三  下午 10:30             1,222 07-客户端.py
               7 个文件          6,816 字节
               2 个目录 124,165,222,400 可用字节

>>>
运行结果

 

10

 

posted @ 2018-03-30 23:36  venicid  阅读(243)  评论(0编辑  收藏  举报