粘包的原因和解决/打印进度条

socket缓冲区

输入输出一边两个缓冲区,缓冲区将程序与网络解耦
服务端为输出缓冲区,信息先进缓冲区,网络通后再走。输入的避免输入太快接受太慢导致拥塞。
取数据时的1024指的是从缓冲区里取的大小。每个缓冲区的大小由电脑的系统配置文件决定 。

粘包现象,在tcp下发生,面向消息流。

1.两个数据都很短,被在缓冲区被优化算法组合为一段内容发送

2.如果客户端一次2000b,两次4000b都在缓冲区,服务端只能1024的一次性接收,接收第一次数据的时候就把后面的一部分也合并进来了。

引入subprocess的简单使用,来模拟和解决粘包现象

第一种方法,不常用

服务端

 1 import  socket,subprocess
 2 server = socket.socket()
 3 ip_port = ('121.195.167.34',8002)
 4 server.bind(ip_port)
 5 server.listen()
 6 conn,add = server.accept()
 7 
 8 while 1:
 9     from_client_cmd = conn.recv(1024)
10 
11     print(from_client_cmd.decode('utf-8'))
12 
13     sub_obj = subprocess.Popen(
14         from_client_cmd.decode('utf-8'),    #这里用于接收客户端发送来的cmd语句
15         shell = True,
16         stdout = subprocess.PIPE,           #运行正常信息所在的管道
17         stderr = subprocess.PIPE            #报错时信息所在的管道
18     )
19     std_msg = sub_obj.stdout.read()         #打印管道内的信息
20     print('指令长度>>>>',len(std_msg))
21     send_len = str(len(std_msg)).encode('utf-8')
22     conn.send(send_len)
23 
24     status = conn.recv(1024).decode('utf-8')
25     if status == 'ok':
26         conn.send(std_msg)
27     else:
28         print(1)

客户端

 1 import socket
 2 client = socket.socket()
 3 ip_port = ('121.195.167.34',8002)
 4 client.connect(ip_port)
 5 
 6 while 1:
 7     cmd = input('请输入cmd指令:')
 8     client.send(cmd.encode('utf-8'))
 9 
10     from_srver_msg = client.recv(1024).decode('utf-8')
11 
12     print('来自服务端额信息长度:',from_srver_msg)
13 
14     client.send(b'ok')
15 
16     server_cmd_result = client.recv(int(from_srver_msg))
17 
18     print(server_cmd_result.decode('gbk'))

由于每次返回的字节过长导致了粘包,所以服务端先返回即将返回的字节长度

客户端获取长度,回复收到,

服务端确认后发送原内容,客户端读取对应长度的内容即可。

但是多了一次对话,效率降低

第二种:

为了避免这个多出来的一次对话,将数据前加入长度

服务端

 1 import socket,subprocess,struct
 2 
 3 server = socket.socket()
 4 ip_port = ('121.195.167.34',8002)
 5 server.bind(ip_port)
 6 server.listen()
 7 while 1:
 8     conn,add = server.accept()
 9 
10     from_client_cmd = conn.recv(1024)
11 
12     sub = subprocess.Popen(
13         from_client_cmd.decode('utf-8'),
14         shell = True,
15         stdout = subprocess.PIPE,
16         stderr = subprocess.PIPE
17     )
18     cmd_result=sub.stdout.read()
19 
20     msg_struct = struct.pack('i',len(cmd_result))
21 
22     conn.send(msg_struct+cmd_result)

客户端

 1 import socket,struct
 2 client = socket.socket()
 3 ip_port = ('121.195.167.34',8002)
 4 client.connect(ip_port)
 5 while 1:
 6     cmd = input('>>>:请输入指令:')
 7     client.send(cmd.encode('utf-8'))
 8     server = client.recv(4)
 9     msg_len = struct.unpack ('i',server)[0]
10     server_result = client.recv(msg_len)
11     print(server_result.decode('gbk'))

打印进度条

1 import time
2 for i in range(0,110,10):
3     print('\r'+str(i)+'%'+(int(i/10)*'**'),end='')
4     time.sleep(1)

 

posted @ 2019-07-31 22:48  眼见高楼起  阅读(190)  评论(0编辑  收藏  举报