Python socket编程-进阶2

解决 粘包现象

所谓粘包现象:

  当一端发生数据的容量大于另外一端一次接收容量,导致另外一端一次只能接受部分数据,其余剩下的数据将保存在缓存里面,当一端再次发送数据的时候,此时另外一端将先在缓存里面取上次剩下的部分数据后在来读取这次发送的数据,

这样就导致发送和接收的数据不一致。

 解决方法:

  采用先发送数据大小,再发送数据

 

server端:

import  socket,subprocess
import  struct


tcp=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
tcp.bind(('localhost',8080,))
tcp.listen(5)

while True:
    conn,address=tcp.accept()
    while True:
        try:
            command=conn.recv(1024).decode('utf-8')
            res=subprocess.Popen(command,shell=True,stderr=subprocess.PIPE,stdin=subprocess.PIPE,stdout=subprocess.PIPE)
            err=res.stderr.read()
            if err:
                cmd_msg=err
            else:
                cmd_msg=res.stdout.read()

            if not cmd_msg:  # 防止指令是正确的,但是结果却是空的,无论是客户端还是服务端都不能发生空消息!
                cmd_msg='没有数据!'.encode('gbk')

            """
                解决粘包思路:
                    1. 先发送数据的长度到客户端
                        struct.pack('i',len(cmd_msg)) 这是一个库, 将一个数据打包,第一个参数为标识(4个字节)也就是发送的大小,第二个参数为要打包的数据
                    2. 再发送数据
            """
            size=struct.pack('i',len(cmd_msg))
            conn.send(size)
            conn.send(cmd_msg)



        except Exception as e:
            print(e)
            break
    conn.close()

tcp.close()

 

client端:

import  socket
import  struct
tcp=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
tcp.connect(('localhost',8080,))



while True:
    command=input('>>>')
    if not command:continue


    tcp.send(command.encode('utf-8'))


    """
        解决粘包思路:
            1. 先接收数据长度
                 struct.unpack('i',size)[0] 这是一个库, 将一个打包数据解压
            2. 再按照数据长度循环读取数据
    """
    size=tcp.recv(4)
    length=struct.unpack('i',size)[0]

    recv_size=0
    recv_msg=b''
    while recv_size<length:
        recv_msg+=tcp.recv(100)
        recv_size=len(recv_msg)


    recv_msg=recv_msg.decode('gbk')
    print(recv_msg)

 

posted @ 2020-12-31 16:53  leungqingyun  阅读(61)  评论(0编辑  收藏  举报