网络编程粘包问题

    首先说为什么会粘包,在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")

原文地址:https://www.cnblogs.com/littlesky1124/p/9043593.html

时间: 2024-09-30 14:20:53

网络编程粘包问题的相关文章

python之网络编程粘包

一.粘包 粘包现象 # 服务端 import socket import subprocess phone = socket.socket() phone.bind(('127.0.0.1',8888)) phone.listen(5) while 1: conn,addr = phone.accept() while 1: cmd = conn.recv(1024) ret = subprocess.Popen(cmd.decode('utf-8'), shell=True, stdout=s

第六章 - 网络编程 - 粘包

1.粘包: 多个包 多个命令的结果 粘到一起了 因为recv 1024限制了 导致的结果 参考:http://www.cnblogs.com/linhaifeng/articles/6129246.html 粘包底层原理分析: 1.运行一个软件 和 哪几个硬件 有关 硬盘 内存 cpu 2.启动程序: 硬盘程序 加载到 内存 启一个软件就占一个内存空间 os 就有一个内存空间 os的内存空间 和 软件的内存空间 彼此互相隔离 须知:只有TCP有粘包现象,UDP永远不会粘包. 所谓粘包问题主要还是

20 网络编程 粘包现象与解决方案

1.https://www.cnblogs.com/guobaoyuan/p/6809447.html 发送数据包前 对包的长度进行计算 1. 比较low的方法是 len( package) 然后直接发送给接收端.这样会出现一个问题,就是接收端不知道你的这个 len(package)是几个字节,就也有可能会出现粘包问题. 2. 利用struct对包的长度打包为固定4个字节或8个字节. 3. struct.pack format参数为"i" 时只能打包长度为10的数字,那么还可以先将 长

TCP网络传输“粘包”问题,经典解决(附代码)

一.前言 关于TCP网络传输粘包,网上很多人写了原理.总结起来就一句话:这里拿Server和Client长连接,Server和Client之间通过信令传输做说明: Server发送的时候按照一条条信令发送,到达操作系统网络层,首先进入缓冲池,然后TCP协议层从池子中获取数据,传输给Client.我们知道TCP的传输有几个方案,比如,滑动窗口.1比特方案.所以Client收到的数据已经不可能是一个个完整的信令的. 个人理解TCP粘包的概念:它描述了一个场景:"信令是一个个紧挨着的,好像是被粘在一起

Python--网络编程-----粘包现象

一.为了防止出现端口占用的情况, linux中可以使用pkill -9 python windows系统中使用taskkill python 二.什么是粘包现象 1.多个包(也就是多个命令的执行结果)粘在一起的现象,叫做粘包现象 2.代码示例如下: 服务端代码: 1 import socket 2 import subprocess 3 4 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 5 # phone.setsockopt

网络编程-----黏包问题

一,黏包现象 我们通过一段简单程序来看看黏包现象: import socket sk=socket.socket() sk.bind(('127.0.0.1',8090)) sk.listen() conn,addr=sk.accept() while True: cmd=input(">>>") if cmd=='q': conn.send(b'q') break conn.send(cmd.encode('gbk')) res=conn.recv(1024).de

socket编程 粘包和半包 问题的及处理

一般在socket处理大数据量传输的时候会产生粘包和半包问题,有的时候tcp为了提高效率会缓冲N个包后再一起发出去,这个与缓存和网络有关系. 粘包 为x.5个包 半包 为0.5个包 由于网络原因 一次可能会来 0.5/1 /2/ 2.5/ ....个包 当接收到时 要先看看那这个包中有多少个完整的包.把完整的包都处理了 也就是说把x都处理了.剩下的0.5留在接收区中,等待下次接收. 这回接收到的就是0.5+1.5/0.5+1.3/0.5+0.5..... 把完整的包都处理了,有残缺的扔掉 0.8

Python之网络编程 黏包

黏包现象 系统缓冲区 缓冲区的作用 没有缓冲区 , 如果你的网路出现短暂的异常或者波动, 接收数据就会出现短暂的中断, 影响你的下载或者上传的效率 但是凡事都有双刃剑, 缓冲区解决了上传下载的传输效率问题 也带来了黏包的问题 讲粘包之前先看看socket缓冲区的问题: 每个 socket 被创建后,都会分配两个缓冲区,输入缓冲区和输出缓冲区. write()/send() 并不立即向网络中传输数据,而是先将数据写入缓冲区中,再由TCP协议将数据从缓冲区发送到目标机器.一旦将数据写入到缓冲区,函数

Java 网络编程 net包

Java提供的通信方式 Socket--面向连接 使用TCP协议,TCP是一种面向连接保证可靠传输的协议.通过TCP协议传输,得到的是一个顺序的无差错的数据流.Java提供的Socket和ServerSocket类支持TCP协议.在发送数据前,发送方和接收方各有一个Socket,它们要建立连接,一旦这两个Socket建立了连接,双方就可以进行双向数据传输,并且所有发送的信息都会在另一端以同样的顺序被接收,安全性高. 服务器程序编写 import java.io.BufferedReader; i