socket+循环通信+粘包

Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。

所谓粘包问题主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的。

 

服务端

from socket import *
import subprocess
import struct
import json

# 创建服务器
server = socket(AF_INET, SOCK_STREAM)
# 给服务器绑定地址
server.bind(('127.0.0.1', 8080))
# 创建半连接池
server.listen(5)

while True:
    # 建立连接
    conn, client_address = server.accept()
    print(client_address)

    while True:
        try:
            # 接受数据
            cmd = conn.recv(1024)
            if len(cmd) == 0:
                break
            obj = subprocess.Popen(cmd.decode('utf-8'),
                                   shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE
                                   )
            stdout = obj.stdout.read()
            stderr = obj.stderr.read()
            # 创建报头
            header_dic = {
                "filename": "a.txt",
                "md5": "jgfjfgsga1972392lsdj",
                "total_size": len(stdout) + len(stderr)
            }
            # 序列化报头
            header_json = json.dumps(header_dic)
            # 将报头转化成bytes格式
            header_bytes = header_json.encode("utf-8")
            
            # 传出数据
            conn.send(struct.pack('i', len(header_bytes)))
            conn.send(header_bytes)
            conn.send(stdout)
            conn.send(stderr)
        except ConnectionResetError:
            break

    conn.close()

server.close()
View Code

客户端

from socket import *
import struct
import json

# 创建客户端
client = socket(AF_INET, SOCK_STREAM)
# 向服务器发送连接请求
client.connect(("127.0.0.1", 8080))

while True:
    cmd = input(">>:").strip()
    if len(cmd) == 0:
        continue
    # 向服务器发送数据
    client.send(cmd.encode("utf-8"))
    
    # 获取报头长度
    header_size = struct.unpack("i", client.recv(4))[0]
    # 获取报头
    header_bytes = client.recv(header_size)
    header_json = header_bytes.decode("utf-8")
    header_dic = json.loads(header_json)
    print(header_dic)
    total_size = header_dic["total_size"]
    
    # 获取数据
    cmd_res = b""
    recv_size = 0
    while recv_size < total_size:
        data = client.recv(1024)
        recv_size += len(data)
        cmd_res += data
    print(cmd_res.decode('gbk'))

client.close()
View Code

 

posted @ 2018-09-03 15:26  い年少有为  阅读(271)  评论(0编辑  收藏  举报