python 之socket 粘包

1、low版本(用户端):

from socket import *
ip_port = ("127.0.0.1",8080)
back_log = 5
buffer_size = 1024
tcp_client = socket(AF_INET,SOCK_STREAM)
tcp_client.connect(ip_port)
while 1:
    cmd = input(">>>>>>>>:").strip()
    if not cmd:
        continue
    if cmd == "quit":
        break
    tcp_client.send(cmd.encode("utf-8"))
    #解决粘包

    length = tcp_client.recv(buffer_size)
    tcp_client.send(b"ready")

    length = int(length.decode("utf-8"))
    recv_size = 0
    recv_msg = b""
    while recv_size < length:
        cmd_res = tcp_client.recv(buffer_size)
        recv_msg = recv_msg + cmd_res
        recv_size = len(recv_msg)
    print("命令的执行结果是",recv_msg.decode("gbk"))
tcp_client.close()

服务端:

from socket import *
import  subprocess
ip_port = ("127.0.0.1",8080)
back_log = 5
buffer_size = 1024
tcp_server = socket(AF_INET,SOCK_STREAM)
tcp_server.bind(ip_port)
tcp_server.listen(back_log)
while 1:
    conn,adr = tcp_server.accept()
    print("新的客户端连接是%s,地址是%s"%(conn,adr))
    while 1:
        try:
            cmd = conn.recv(buffer_size)
            if not cmd:
                break
            print("收到客户端的命令",cmd)
            res = subprocess.Popen(cmd.decode("utf-8"),shell= True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=subprocess.PIPE)
            err = res.stderr.read()
            # if not err:#为空
            if err:#有值
                cmd = err
            else:
                cmd_res = res.stdout.read()#bite

            if not cmd_res:
                cmd_res = "执行成功".encode("gbk")

            length = len(cmd_res)

            conn.send(str(length).encode("utf-8"))

            client_ready = conn.recv(buffer_size)

            if client_ready == b"ready":

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

2、高逼格版本:(提升性能)

用户端:

from socket import *
import  struct
ip_port = ("127.0.0.1",8080)
back_log = 5
buffer_size = 1024
tcp_client = socket(AF_INET,SOCK_STREAM)
tcp_client.connect(ip_port)
while 1:
    cmd = input(">>>>>>>>:").strip()
    if not cmd:
        continue
    if cmd == "quit":
        break
    tcp_client.send(cmd.encode("utf-8"))
    #解决粘包
    length_data = tcp_client.recv(4)
    length = struct.unpack("i",length_data)[0]
    recv_size = 0
    recv_msg = b""
    while recv_size < length:
        cmd_res = tcp_client.recv(buffer_size)
        recv_msg = recv_msg + cmd_res
        recv_size = len(recv_msg)
    print("命令的执行结果是",recv_msg.decode("gbk"))
tcp_client.close()

 服务端:

from socket import *
import  subprocess
import struct
ip_port = ("127.0.0.1",8080)
back_log = 5
buffer_size = 1024
tcp_server = socket(AF_INET,SOCK_STREAM)
tcp_server.bind(ip_port)
tcp_server.listen(back_log)
while 1:
    conn,adr = tcp_server.accept()
    print("新的客户端连接是%s,地址是%s"%(conn,adr))
    while 1:
        try:
            cmd = conn.recv(buffer_size)
            if not cmd:
                break
            print("收到客户端的命令",cmd)
            res = subprocess.Popen(cmd.decode("utf-8"),shell= True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=subprocess.PIPE)
            err = res.stderr.read()
            # if not err:#为空
            if err:#有值
                cmd = err
            else:
                cmd_res = res.stdout.read()#bite
            if not cmd_res:
                cmd_res = "执行成功".encode("gbk")
            length = len(cmd_res)
            data_length = struct.pack("i",length)
            conn.send(data_length)
            conn.send(cmd_res)
        except Exception as e:
            print(e)
            break
    conn.close()

原文地址:https://www.cnblogs.com/huoyunxieshen/p/10123778.html

时间: 2024-10-27 05:07:17

python 之socket 粘包的相关文章

[转]关于Socket粘包问题

这两天看csdn有一些关于socket粘包,socket缓冲区设置的问题,发现自己不是很清楚,所以查资料了解记录一下: 一两个简单概念长连接与短连接:1.长连接 Client方与Server方先建立通讯连接,连接建立后不断开, 然后再进行报文发送和接收. 2.短连接 Client方与Server每进行一次报文收发交易时才进行通讯连接,交易完毕后立即断开连接.此种方式常用于一点对多点 通讯,比如多个Client连接一个Server. 二 什么时候需要考虑粘包问题? 1:如果利用tcp每次发送数据,

C#下利用封包、拆包原理解决Socket粘包、半包问题(新手篇)

介于网络上充斥着大量的含糊其辞的Socket初级教程,扰乱着新手的学习方向,我来扼要的教一下新手应该怎么合理的处理Socket这个玩意儿. 一般来说,教你C#下Socket编程的老师,很少会教你如何解决Socket粘包.半包问题. 更甚至,某些师德有问题的老师,根本就没跟你说过Socket的粘包.半包问题是什么玩意儿. 直到有一天,你的Socket程序在传输信息时出现了你预期之外的结果(多于的信息.不完整的信息.乱码.Bug等等). 任你喊了一万遍“我擦”,依旧是不知道问题出在哪儿! 好了,不说

Socket粘包问题

这两天看csdn有一些关于socket粘包,socket缓冲区设置的问题,发现自己不是很清楚,所以查资料了解记录一下: 一两个简单概念长连接与短连接:1.长连接 Client方与Server方先建立通讯连接,连接建立后不断开, 然后再进行报文发送和接收. 2.短连接 Client方与Server每进行一次报文收发交易时才进行通讯连接,交易完毕后立即断开连接.此种方式常用于一点对多点 通讯,比如多个Client连接一个Server. 二 什么时候需要考虑粘包问题? 1:如果利用tcp每次发送数据,

TCP Socket 粘包

 这两天看csdn有一些关于socket粘包,socket缓冲区设置的问题,发现自己不是很清楚,所以查资料了解记录一下: 一两个简单概念长连接与短连接: 1.长连接 Client方与Server方先建立通讯连接,连接建立后不断开, 然后再进行报文发送和接收. 2.短连接 Client方与Server每进行一次报文收发交易时才进行通讯连接,交易完毕后立即断开连接.此种方式常用于一点对多点 通讯,比如多个Client连接一个Server. 二 什么时候需要考虑粘包问题? 1:如果利用tcp每次发

Python socket粘包问题

server端配置: import socket,subprocess,struct from socket import * server=socket(AF_INET,SOCK_STREAM) server.bind(('127.0.0.1',8080)) server.listen(5) while True: conn,client_addr=server.accept() while True: try: cmd=conn.recv(1024) if len(cmd) == 0:bre

socket 粘包问题(转)

https://www.v2ex.com/t/234785#reply3 1. 面向字节流的 IO 都有这个问题. socket 中 tcp 协议是面向流的协议,发送方发送和接收方的接收并不是一一对应的.所以造成所谓的粘包现象. 怎么处理呢? 方法 1 :协议包定长. 每个发送出去的包长度固定.比如都是 10 个字节.收的时候每次就收 10 个字节,当一个完整的数据包. 方法 2 :告知包的长度 协议头开始固定长度的字节告知后续包长.收方先收包长字节,知道了后续包长后再收. 方法 3 :用一个包

Java nio socket与as3 socket(粘包解码)连接的应用实例

对Java nio socket与as3 socket连接的简单应用 <ignore_js_op>Java nio socket与as3 socket连接的应用实例.rar (9.61 KB, 下载次数: 1691) 这个从基本的弄起太复杂了,我弄个了mina与flash通信的,通信数据模式是dataLength+data(数据长度+数据内容),对于socket字节流通信,我习惯用这种方式,方便粘包解码处理.其中已包含所需的jar包,客户端代码须另自写,不可沿用.flash socket发送的

C# SOCKET 粘包、断包处理(一)

一直是用JAVA,关于SOCKET方面,JAVA有一个不错的框架MINA2,对于粘包.断包的处理有这个良好的处理,个人需要写的代码并不太多. 而C#.因为了解不多,也没去看第三方的SOCKET框架,所以只好根据MSDN提示,自己去实现了. 在代码之前,我们先说说处理中会碰到的情况如何: 1.先假设数据包的格式如下: 包长度(4字节)MD5签名(32字节)客户端ID(5字节)数据类型(5字节)数据ID(32字节)数据内容(动态长度.不固定) |---------------------------

socket 粘包

产生粘包: 1.发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据了很小,会合到一起,产生粘包) 2.接收方不及时接收缓冲区的包,造成多个包接收(客户端发送了一段数据,服务端只收了一小部分, 服务端下次再收的时候还是从缓冲区拿上次遗留的数据,产生粘包) 所谓粘包问题主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的. 补充: recv里指定的1024意思是从缓存里一次拿出1024个字节的数据 send的字节流是先放入己端缓存,然后由协议控制将缓存内容