网络编程粘包问题

Posted Talk is cheap 。

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络编程粘包问题相关的知识,希望对你有一定的参考价值。

    首先说为什么会粘包,在py2上运行时,服务器把两次发送的操作强制的合成一次发送给客户端,所以 粘在一起了,因为python3的版本是可以的,但是有的时候python3也会出现粘包现象。

  解决粘包的问题有两种方法:

    1  可以先sleep一下,这个样子就可以使缓冲区超时,就不在等下一次的了,这样就可以和下一条命令隔离开了

    2  我在服务端来一个等待客户端确认,就ok了,这个确认不需要我们用户输入,而是客户端自动的给你来这个响应,就是说,客户端自动的写好代码,自动的给服务器一个响应,只要收到服务端的数据大小,我就立刻给服务器一个响应,就是在第一次send和第二次send之前插入一个交互,就能把数据分开了。

      下面也有两次send 的原因。

 

 

代码:中间空白分割的部分

#!usr/bin/env phthon3
# -*- coding:utf-8 -*-
# _Author_:"zhang Yaoqing"

import socket

client = socket.socket()
client.connect(("localhost", 9999))

while True:
    cmd = input(">>>:").strip()
    if len(cmd) == 0: continue
    client.send(cmd.encode("utf-8"))
    cmd_res_size = client.recv(500)  # 接收命令的长度
    print("命令结果大小:", cmd_res_size.decode())


    client.send(准备好了,可以发送了.encode(utf-8))       # 客户端已经确认。



    recevied_size = 0  # 接收客户端发来数据的计算器
    recevied_data = b‘‘  # 客户端每次发来内容的计数器
    while recevied_size < int(cmd_res_size.decode()):  # 当接收的数据大小 小于 客户端发来的数据
        cmd_res = client.recv(500)
        recevied_size += len(cmd_res)  # 每次收到的服务端的数据有可能小于1024,所以必须用len判断
        recevied_data += cmd_res
    else:
        print(recevied_data.decode("utf-8", "ignore"))
        print("cmd res receive done ....", recevied_size)

 

#!usr/bin/env phthon3
# -*- coding:utf-8 -*-
# _Author_:"zhang Yaoqing"

import socket, os

server = socket.socket()
server.bind(("localhost", 9999))
server.listen(5)
while True:
    conn, addr = server.accept()
    print("new addr:", addr)
    print(conn,conn)
    while True:
        data = conn.recv(500)
        if not data:
            print("客户端已断开")
            break
        print("执行指令:", data)
        cmd_res = os.popen(data.decode()).read()
        print("before send:", len(cmd_res))
        if len(cmd_res) == 0:
            cmd_res = "cmd has no output...."
        conn.send(str(len(cmd_res.encode())).encode())  # 发送服务端发送给客户端数据的长度


        client_ack = conn.recv(1024)  # 等待确认


        conn.send(cmd_res.encode("utf-8"))  # 发送服务端的数据
        print("send done")

 

以上是关于网络编程粘包问题的主要内容,如果未能解决你的问题,请参考以下文章

socket网络编程:粘包现象以及解决方法(代码完善)

Java网络编程——粘包拆包出现的原因及解决方式

Java网络编程——粘包拆包出现的原因及解决方式

Java网络编程——粘包拆包出现的原因及解决方式

Java网络编程——粘包拆包出现的原因及解决方式

网络编程基础之粘包现象