Python之网络编程与粘包现象

socket基于tcp连接示例:

server端代码:

import socket
sk = socket.socket() # 创建一个socket对象
# 又是重启服务端报错“OSError: [WinError 10048] 通常每个套接字地址(协议/网络地址/端口)只允许使用一次”
sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) # 开启端口重用,防止连接没有释放报错
address = ('127.0.0.1',8098)
sk.bind(address) # 绑定IP和端口
sk.listen(5)

conn,add = sk.accept() # 等待连接,返回一个连接操作符和客户端地址
ret = conn.recv(1024).decode(encoding='utf-8') # 接收客户端的信息
print(ret)

conn.close() # 关闭连接
sk.close() # 关闭socket对象

client端代码:

import socket
sk = socket.socket() # 创建一个socket对象
address = ('127.0.0.1',8098)
sk.connect(address) # 连接服务端
sk.send(bytes('hello every one',encoding='utf-8')) # 给服务端发送一个消息

sk.close() # 关闭连接

socket基于udp示例:

server端代码:

# udp 服务端
import socket

sk = socket.socket(type=socket.SOCK_DGRAM) # 用户数据报协议--udp
address = ('127.0.0.1',8098)
sk.bind(address)
ret,addr = sk.recvfrom(1024)
print(ret.decode(encoding='utf-8'))
sk.sendto(bytes('hello,wellcome!',encoding='utf-8'),addr)
sk.close()

client端代码:

# udp 客户端
import socket
sk = socket.socket(type=socket.SOCK_DGRAM)
address = ('127.0.0.1',8098)
sk.sendto(bytes('hello every one',encoding='utf-8'),address)
ret,addr = sk.recvfrom(1024)
print(ret.decode(encoding='utf-8'))
sk.close()

subprocess模块基本用法:

import subprocess
# dir--执行的命令,stdout--标准输出,stderr--标准错误输出
res = subprocess.Popen('dir',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
ret = res.stdout.read().decode(encoding='gbk') # 获取标准输出的结果
print(ret)
# 输出WIN当前目录的下的文件,WIN默认gbk编码,需要节码程unicode查看

#  粘包现象

server端代码:

# tcp粘包现象
import socket

sk = socket.socket()
address = ('127.0.0.1',8098)
sk.bind(address)
sk.listen(5)
conn,addr = sk.accept()
ret = conn.recv(1024).decode(encoding='gbk')
print(ret)
while True:
    command = input(">>>")
    conn.send(command.encode(encoding='gbk'))
    if command == "bye":
        break
    # ret1 = conn.recv(1024).decode(encoding='utf-8')
    # ret2 = conn.recv(1024).decode(encoding='utf-8')
    ret1 = conn.recv(2048)
    ret2 = conn.recv(2048)
    print(ret1.decode('utf-8'))
    print(ret2.decode('utf-8'))
conn.close()
sk.close()

server段测试输出:

please input command:
>>>dir
stdout: 驱动器 D 中的卷是 DATA
 卷的序列号是 DE8A-E1A1

 D:\PYTHON\Process\python_learning\day04 的目录

2019/04/06  23:57    <DIR>          .
2019/04/06  23:57    <DIR>          ..
2019/03/09  22:45                99 json.txt
2018/11/30  23:31                31 log
2019/04/05  17:19               806 new_test.log
2019/04/05  17:19             2,000 new_test.log.1
2019/04/05  17:18             2,010 new_test.log.2
2019/03/09  22:57               180 pickle.txt
2019/03/25  22:19             3,534 Python中的接口类与抽象类.py
2019/03/09  23:03                57 shelve_file.bak
2019/03/09  23:03             1,084 shelve_file.dat
2019/03/09  23:03                57 shelve_file.dir
2019/04/05  15:44               418 test.log
2019/04/05  16:07               572 test1.log
2019/04/05  16:47             2,746 test2.log
2018/11/25  21:49                 0 __init__.py
2019/02/24  22:52             3,251 内置函数.py
2019/04/05  17:21             9,999 单例模式与几个常用模块.py
2019/04/01  19:51             2,993 反射.py
2019/02/19  22:56             3,414 命名空间.py
2019/03/09  23:04             8,131 常用模块.py
2019/03/10  14:55             1,312 异常处理.py
2019/03/26  23:15             2,518 特性,静态方法与类方法.py
2019/02/23  18:49             4,298 生成器与装饰器进阶.py
2019/02/24  16:36             2,767 生成器进阶.py
2018/11/25  22:27             1,324 第四天.py
2019/03/10  20:59             1,808 类的命名空间.py
2019/04/06  23:57             1,169 网络编程-client.py
2019/04/06  23:57             2,365 网络编程-server.py
2019/02/23  16:52             3,430 装饰器一.py
2019/02/23  20:19               482 迭代器与生成器.py
2019/02/25  23:28             9,505 递归函数.py
2018/11/29  00:11               518 递归找文件.py
2018/11/30  23:31               108 重定向测试.py
2019/03/10  19:27             1,905 面向对象_l类.py
2019/03/20  21:12             6,09
6 面向对象三大特性.py
2019/03/20  22:03                 0 面向对象接口类与抽象类.py
              35 个文件         80,987 字节
               2 个目录 123,810,537,472 可用字节
stderr:
>>>ls
stdout:
stderr:'ls' 不是内部或外部命令,也不是可运行的程序
或批处理文件。

>>>ipconfig
stdout:
Windows IP 配置


以太网适配器 以太网 2:

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

无线局域网适配器 本地连接* 2:

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

无线局域网适配器 本地连接* 3:

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

以太网适配器 VMware Network Adapter VMnet1:

   连接特定的 DNS 后缀 . . . . . . . : 
   本地链接 IPv6 地址. . . . . . . . : xxxxxx
   IPv4 地址 . . . . . . . . . . . . : xxxxxxxx
   子网掩码  . . . . . . . . . . . . : 255.255.255.0
   默认网关. . . . . . . . . . . . . : 

以太网适配器 VMware Network Adapter VMnet8:

   连接特定的 DNS 后缀 . . . . . . . : 
   本地链接 IPv6 地址. . . . . . . . : xxxxxxxx
   IPv4 地址 . . . . . . . . . . . . : xxxxxxxxxxxxx
   子网掩码  . . . . . . . . . . . . : 255.255.255.0
   默认网关. . . . . . . . . . . . . : 

以太网适配器 VMware Network Adapter VMnet2:

   连接特定的 DNS 后缀 . . . . . . . : 
   本地链接 IPv6 地址. . . . . . . . : xxxxxxxxxxxxxx
   IPv4 地址 . . . . . . . . . . . . : xxxxxxxxxxxxxxx
   子网掩码  . . . . . . . . . . . . : 255.255.255.0
   默认网关. . . . . . . . . . . . . : 

无线局域网适配器 WLAN:

   连接特定的 DNS 后缀 . . . . . . . : 
   IPv6 地址 . . . . . . . . . . . . : xxxxxxxxxxxxxxx
   临时 IPv6 地址. . . . . . . . . . : xxxxxxxxxxxxxxxxxxxxx
   本地链接 IPv6 地址. . . . . . . . : xxxxxxxxxxxxxxxx
   IPv4 地址 . . . . . . . . . . . . : xxxxxxxxxxxxxxxxxxxxx
   子网掩码  . . . . . . . . . . . . : xxxxxxxxxxxxxxxxxxx
   默认网关. . . . . . . . . . . . . : xxxxxxxxxxxxxxxxx
                                       192.168.1
.1

以太网适配器 蓝牙网络连接 2:

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

>>>ls
stderr:
stdout:
>>>ls
stderr:'ls' 不是内部或外部命令,也不是可运行的程序
或批处理文件。

stdout:
>>>dir
stderr:'ls' 不是内部或外部命令,也不是可运行的程序
或批处理文件。

stdout: 驱动器 D 中的卷是 DATA
 卷的序列号是 DE8A-E1A1

 D:\PYTHON\Process\python_learning\day04 的目录

2019/04/06  23:57    <DIR>          .
2019/04/06  23:57    <DIR>          ..
2019/03/09  22:45                99 json.txt
2018/11/30  23:31                31 log
2019/04/05  17:19               806 new_test.log
2019/04/05  17:19             2,000 new_test.log.1
2019/04/05  17:18             2,010 new_test.log.2
2019/03/09  22:57               180 pickle.txt
2019/03/25  22:19             3,534 Python中的接口类与抽象类.py
2019/03/09  23:03                57 shelve_file.bak
2019/03/09  23:03             1,084 shelve_file.dat
2019/03/09  23:03                57 shelve_file.dir
2019/04/05  15:44               418 test.log
2019/04/05  16:07               572 test1.log
2019/04/05  16:47             2,746 test2.log
2018/11/25  21:49                 0 __init__.py
2019/02/24  22:52             3,251 内置函数.py
2019/04/05  17:21             9,999 单例模式与几个常用模块.py
2019/04/01  19:51             2,993 反射.py
2019/02/19  22:56             3,414 命名空间.py
2019/03/09  23:04             8,131 常用模块.py
2019/03/10  14:55             1,312 异常处理.py
2019/03/26  23:15             2,518 特性,静态方法与类方法.py
2019/02/23  18:49             4,298 生成器与装饰器进阶.py
2019/02/24  16:36             2,767 生成器进阶.py
2018/11/25  22:27             1,324 第四天.py
2019/03/10  20:59             1,808 类的命名空间.py
2019/04/06  23:57             1,169 网络编程-client.py
2019/04/06  23:57             2,365 网络编程-server.py
2019/02/23  16:52             3,430 装饰器一.py
2019/02/23  20:19               482 迭代器与生成器.py
2019/02/25  23:28             9,505 递归函数.py
2018/11/29  00:11               518 递归找文件.py
2018/11/30  23:31               108 重定向测试.py
2019/03/10  19:27             1,905 面向对象_l类.py
2019/03/20  21:12             6,09
>>>ls
6 面向对象三大特性.py
2019/03/20  22:03                 0 面向对象接口类与抽象类.py
              35 个文件         80,987 字节
               2 个目录 123,810,537,472 可用字节
stderr:
stdout:

client端代码:

# 接受命令
import socket,time
import subprocess
sk = socket.socket()
address = ('127.0.0.1',8098)
sk.connect(address)
sk.send(bytes('please input command:',encoding='gbk'))
while True:
    ret = sk.recv(1024).decode(encoding='gbk')
    print(ret)
    if ret == "bye":
        break
    res = subprocess.Popen(ret,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    stdout = 'stdout:' + res.stdout.read().decode(encoding='gbk')
    stderr = 'stderr:' + res.stderr.read().decode(encoding='gbk')
    print(stdout)
    print(stderr)
    sk.send(stdout.encode('utf-8'))
    sk.send(stderr.encode('utf-8'))
sk.close()

client端测试输出:

client端:
dir
stdout: 驱动器 D 中的卷是 DATA
 卷的序列号是 DE8A-E1A1

 D:\PYTHON\Process\python_learning\day04 的目录

2019/04/06  23:57    <DIR>          .
2019/04/06  23:57    <DIR>          ..
2019/03/09  22:45                99 json.txt
2018/11/30  23:31                31 log
2019/04/05  17:19               806 new_test.log
2019/04/05  17:19             2,000 new_test.log.1
2019/04/05  17:18             2,010 new_test.log.2
2019/03/09  22:57               180 pickle.txt
2019/03/25  22:19             3,534 Python中的接口类与抽象类.py
2019/03/09  23:03                57 shelve_file.bak
2019/03/09  23:03             1,084 shelve_file.dat
2019/03/09  23:03                57 shelve_file.dir
2019/04/05  15:44               418 test.log
2019/04/05  16:07               572 test1.log
2019/04/05  16:47             2,746 test2.log
2018/11/25  21:49                 0 __init__.py
2019/02/24  22:52             3,251 内置函数.py
2019/04/05  17:21             9,999 单例模式与几个常用模块.py
2019/04/01  19:51             2,993 反射.py
2019/02/19  22:56             3,414 命名空间.py
2019/03/09  23:04             8,131 常用模块.py
2019/03/10  14:55             1,312 异常处理.py
2019/03/26  23:15             2,518 特性,静态方法与类方法.py
2019/02/23  18:49             4,298 生成器与装饰器进阶.py
2019/02/24  16:36             2,767 生成器进阶.py
2018/11/25  22:27             1,324 第四天.py
2019/03/10  20:59             1,808 类的命名空间.py
2019/04/06  23:57             1,169 网络编程-client.py
2019/04/06  23:57             2,365 网络编程-server.py
2019/02/23  16:52             3,430 装饰器一.py
2019/02/23  20:19               482 迭代器与生成器.py
2019/02/25  23:28             9,505 递归函数.py
2018/11/29  00:11               518 递归找文件.py
2018/11/30  23:31               108 重定向测试.py
2019/03/10  19:27             1,905 面向对象_l类.py
2019/03/20  21:12             6,096 面向对象三大特性.py
2019/03/20  22:03                 0 面向对象接口类与抽象类.py
              35 个文件         80,987 字节
               2 个目录 123,810,537,472 可用字节

stderr:
ls
stdout:
stderr:'ls' 不是内部或外部命令,也不是可运行的程序
或批处理文件。

ipconfig
stdout:
Windows IP 配置


以太网适配器 以太网 2:

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

无线局域网适配器 本地连接* 2:

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

无线局域网适配器 本地连接* 3:

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

以太网适配器 VMware Network Adapter VMnet1:

   连接特定的 DNS 后缀 . . . . . . . : 
   本地链接 IPv6 地址. . . . . . . . : fe80::7c68:c6fa:c24a:6132%5
   IPv4 地址 . . . . . . . . . . . . : 192.168.52.1
   子网掩码  . . . . . . . . . . . . : 255.255.255.0
   默认网关. . . . . . . . . . . . . : 

以太网适配器 VMware Network Adapter VMnet8:

   连接特定的 DNS 后缀 . . . . . . . : 
   本地链接 IPv6 地址. . . . . . . . : fe80::5c05:b63e:d430:e8e6%4
   IPv4 地址 . . . . . . . . . . . . : 192.168.10.1
   子网掩码  . . . . . . . . . . . . : 255.255.255.0
   默认网关. . . . . . . . . . . . . : 

以太网适配器 VMware Network Adapter VMnet2:

   连接特定的 DNS 后缀 . . . . . . . : 
   本地链接 IPv6 地址. . . . . . . . : fe80::5470:797d:d576:3eb5%11
   IPv4 地址 . . . . . . . . . . . . : 192.168.159.1
   子网掩码  . . . . . . . . . . . . : 255.255.255.0
   默认网关. . . . . . . . . . . . . : 

无线局域网适配器 WLAN:

   连接特定的 DNS 后缀 . . . . . . . : 
   IPv6 地址 . . . . . . . . . . . . : xxxxxxxxxxxxxxxxx
   临时 IPv6 地址. . . . . . . . . . : xxxxxxxxxxxxxxxxxxx
   本地链接 IPv6 地址. . . . . . . . : xxxxxxxxxxxxxxxxxx
   IPv4 地址 . . . . . . . . . . . . : xxxxxxxxxxxxxxxxxxxxxx
   子网掩码  . . . . . . . . . . . . : 255.255.255.0
   默认网关. . . . . . . . . . . . . : xxxxxxxxxxxxxxxxxxxxx
                                       192.168.1.1

以太网适配器 蓝牙网络连接 2:

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

stderr:
ls
stdout:
stderr:'ls' 不是内部或外部命令,也不是可运行的程序
或批处理文件。

ls
stdout:
stderr:'ls' 不是内部或外部命令,也不是可运行的程序
或批处理文件。

dir
stdout: 驱动器 D 中的卷是 DATA
 卷的序列号是 DE8A-E1A1

 D:\PYTHON\Process\python_learning\day04 的目录

2019/04/06  23:57    <DIR>          .
2019/04/06  23:57    <DIR>          ..
2019/03/09  22:45                99 json.txt
2018/11/30  23:31                31 log
2019/04/05  17:19               806 new_test.log
2019/04/05  17:19             2,000 new_test.log.1
2019/04/05  17:18             2,010 new_test.log.2
2019/03/09  22:57               180 pickle.txt
2019/03/25  22:19             3,534 Python中的接口类与抽象类.py
2019/03/09  23:03                57 shelve_file.bak
2019/03/09  23:03             1,084 shelve_file.dat
2019/03/09  23:03                57 shelve_file.dir
2019/04/05  15:44               418 test.log
2019/04/05  16:07               572 test1.log
2019/04/05  16:47             2,746 test2.log
2018/11/25  21:49                 0 __init__.py
2019/02/24  22:52             3,251 内置函数.py
2019/04/05  17:21             9,999 单例模式与几个常用模块.py
2019/04/01  19:51             2,993 反射.py
2019/02/19  22:56             3,414 命名空间.py
2019/03/09  23:04             8,131 常用模块.py
2019/03/10  14:55             1,312 异常处理.py
2019/03/26  23:15             2,518 特性,静态方法与类方法.py
2019/02/23  18:49             4,298 生成器与装饰器进阶.py
2019/02/24  16:36             2,767 生成器进阶.py
2018/11/25  22:27             1,324 第四天.py
2019/03/10  20:59             1,808 类的命名空间.py
2019/04/06  23:57             1,169 网络编程-client.py
2019/04/06  23:57             2,365 网络编程-server.py
2019/02/23  16:52             3,430 装饰器一.py
2019/02/23  20:19               482 迭代器与生成器.py
2019/02/25  23:28             9,505 递归函数.py
2018/11/29  00:11               518 递归找文件.py
2018/11/30  23:31               108 重定向测试.py
2019/03/10  19:27             1,905 面向对象_l类.py
2019/03/20  21:12             6,096 面向对象三大特性.py
2019/03/20  22:03                 0 面向对象接口类与抽象类.py
              35 个文件         80,987 字节
               2 个目录 123,810,537,472 可用字节

stderr:
ls
stdout:
stderr:'ls' 不是内部或外部命令,也不是可运行的程序
或批处理文件。

可以看出client端结果规律遵循命令->stdout->stderr,这样的规律,server端接收到的结果顺序被打乱,出现上一个命令的部分结果再下一个命令结果中返回,即时发生了粘包现象

猜你喜欢

转载自blog.csdn.net/qq_40199698/article/details/89062325