socket通信中如何区分前后两次的数据

【导读】在socket通信中,通信内核层会做缓冲,使得前后两次发送的数据缓冲到一起,导致接收方接收到的数据是一整块,无法区分。

【正文】

1. 在发送方和接收方约定相同的长度,发送方进行用特殊的标志对数据进行末尾补齐,接收方将数据过滤掉特殊的标志。

示例:双方约定能处理的最大数据长度是1024,

发送方:发送字符串"abc"时,有效长度是3,需要补齐 1024 - 3 = 1021个“\0”字符(不同编程语言里,这个特殊的字符需要看情况指定)。python代码:

class Session():
    
    BUFF_SIZE = 512
    
    TAG_STR = "\0"
 
 
    def __preprocess_send_data(self, data):
        str_len = len(data)
        need_num = Session.BUFF_SIZE - str_len % Session.BUFF_SIZE
        final_len = str_len + need_num
        tmp_data = data + need_num * Session.TAG_STR
        
        data_list = []
        for i in range(0, final_len, Session.BUFF_SIZE):
            data_list.append(tmp_data[i : i + Session.BUFF_SIZE])
        
        return data_list

调用:
data_list = self.__preprocess_send_data(data)
for sub_data in data_list:
    self.__socket.send(sub_data)

接收方:接收到长度为1024的字符串,找到第一个‘\0’字符出现的位置,此位置之前的为有效串。

def __preprocess_recv_data(self, data):
        index = data.find(Session.TAG_STR)
        return data[0:index]
 
调用:
    data = self.__socket.recv(Session.BUFF_SIZE)
    if data:
        data = self.__preprocess_recv_data(data)

 

2. 在发送数据末尾加上特殊标识,接收方在接收到数据时,需要判断当前数据是否包含了特殊标记,如果包含了,则特殊标记之前的字符串为有效的一次数据记录。否则,存储起来,直到后续碰到特殊标记。

发送方:send(data + 特殊标记串)

接收方:

valid_str = "" # 有效的待处理字符串
last_left = "" # 上一次留下来的待处理串
 
while True:
    data = self.__socket.recv(Session.BUF_SIZE)
    index = data.find(特殊字符串)
    if index >= 0:
        valid_str = last_left + data[0:index]
        last_left = data[index + len(特殊字符串):]
    else:
        valid_str = ""
        last_left += data
        
    if len(valid_str) > 0:
        # 处理

两种方案的比较:

方案1增加了通信带宽,但容易使用和理解;

方案2节约了通信带宽,对于接收方来说,计算逻辑会更复杂。对于带宽要求较高的场景,建议用方案2.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值