Python 解决粘包

发送数据包前 对包的长度进行计算

1. 比较low的方法是 len( package) 然后直接发送给接收端。这样会出现一个问题,就是接收端不知道你的这个 len(package)是几个字节,就也有可能会出现粘包问题。

2. 利用struct对包的长度打包为固定4个字节或8个字节。

3. struct.pack format参数为"i" 时只能打包长度为10的数字,那么还可以先将 长度 转换为一个json字符串,再打包。

 

 

Server端

# -*- coding:utf-8 -*-

from socketserver import ThreadingTCPServer, StreamRequestHandler
import struct
import subprocess


class MyRequestHandler(StreamRequestHandler):

    def handle(self):

        while True:
            print("connect from:", self.client_address)
            cmd = bytes.decode(self.request.recv(1024))
       if not cmd: break res
= subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) err = res.stderr.read() if err: back_msg = err else: back_msg = res.stdout.read() self.request.send(struct.pack("i", len(back_msg))) self.request.send(back_msg) if __name__ == '__main__': tcp_Server = ThreadingTCPServer(("127.0.0.1", 8081), MyRequestHandler) tcp_Server.allow_reuse_address = True tcp_Server.serve_forever()

 

Client端

# -*- coding:utf-8 -*-

import socket
import struct

host = "127.0.0.1"
port = 8081

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))

while True:
    cmd = input(">>>>").strip()
    if not cmd:
        continue
    s.send(cmd.encode("utf-8"))

    package_len = s.recv(4)
    package_size = struct.unpack("i",package_len)[0]

    recv_size = 0
    recv_bytes = b""

    while recv_size < package_size:
        res = s.recv(1024)
        recv_bytes += res
        recv_size += len(res)

    print(recv_bytes.decode("utf-8"))

s.close()

 

posted @ 2017-03-04 18:49  Vincen_shen  阅读(1363)  评论(0)    收藏  举报