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


    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('
    '+str(i)+'%'+(int(i/10)*'**'),end='')
    4     time.sleep(1)
  • 相关阅读:
    ACM-ICPC 2018 徐州赛区网络预赛 J. Maze Designer (最大生成树+LCA)
    ACM-ICPC 2018 沈阳赛区网络预赛 F. Fantastic Graph (上下界网络流)
    ACM-ICPC 2018 沈阳赛区网络预赛 G. Spare Tire (容斥原理)
    HDU 3081 Marriage Match II (二分+并查集+最大流)
    ISAP模板
    POJ
    青春
    登高有感
    那年今日
    NOIP200101数的计算
  • 原文地址:https://www.cnblogs.com/shachengcc1/p/11279705.html
Copyright © 2020-2023  润新知