Python網路程式設計,粘包 分包問題的解決

2022-03-02 14:32:51 字數 3640 閱讀 2153

tcp程式設計中的粘包、分包問題的解決:

參考:服務端:

#!/bin/env python

# -*- coding:utf-8 -*-

import socket

import time

import struct

import json

import socket

import sys

class sockpackbody():

def __init__(self , data_buffer = bytes() , header_size = 4):

self.data_buffer = data_buffer

self.header_size = header_size

self.header = none

self.body_size = 0

self.body = none

def packbody(self , sock):

while true:

'''一次接收迴圈'''

recv_pkg = sock.recv(1024)

if not recv_pkg and len(self.data_buffer) == 0 :

'''connect closed , and no data in buffer.'''

return none

self.data_buffer += recv_pkg

if len(self.data_buffer) < self.header_size:

'''接收到的資料報小於self.headersize,說明連包頭都沒接受完整'''

continue

self.header = struct.unpack("!1i" , self.data_buffer[:self.header_size])

self.body_size = self.header[0]

#分包if len(self.data_buffer) < self.header_size + self.body_size:

'''接收到的資料報小於self.header_size + self.body_size,說明整個資料報都沒接受完整'''

continue

self.body = self.data_buffer[self.header_size:self.header_size + self.body_size]

#粘包self.data_buffer = self.data_buffer[self.header_size + self.body_size:]

return self.body

if __name__ == '__main__':

sock_pkger = sockpackbody()

sock = socket.socket(socket.af_inet , socket.sock_stream)

sock.bind(('0.0.0.0' , 6688))

sock.listen(5)

agent_sock , agent_addr = sock.accept()

n = 1

while true:

'''一次連線(會話)迴圈'''

recv_data = sock_pkger.packbody(agent_sock)

if not recv_data:

agent_sock.close()

break

print recv_data

客戶端:

import socket

import time

import struct

import json

import sys

reload(sys)

sys.setdefaultencoding('utf-8')

serve_host = "localhost"

server_port = 6688

class pkgbuildheader(object):

def __init__(self, body_size ,):

self.pack_header = struct.pack("!1i", body_size)

if __name__ == '__main__':

client = socket.socket()

client.connect(serve_host , server_port)

# 正常資料報定義

body = '''link encap:ethernet hwaddr 00:0c:29:ef:84:a3

inet addr:192.168.31.140 bcast:192.168.31.255 mask:255.255.255.0

inet6 addr: fe80::20c:29ff:feef:84a3/64 scope:link

up broadcast running multicast mtu:1500 metric:1

rx packets:236844 errors:0 dropped:0 overruns:0 frame:0

tx packets:233949 errors:0 dropped:0 overruns:0 carrier:0

collisions:0 txqueuelen:1000

rx bytes:107658740 (102.6 mib) tx bytes:41874253 (39.9 mib)

'''header = pkgbuildheader(len(body))

senddata1 = header.pack_header + body.encode()

# 分包資料定義

header = pkgbuildheader(len(body))

senddata2_1 = header.pack_header+body[:20].encode()

senddata2_2 = body[20:].encode()

# 粘包資料定義

body1 = "link encap:ethernet hwaddr 00:0c:29:ef:84:a3"

header1 = pkgbuildheader(len(body1))

body2 = "rx bytes:107658740 (102.6 mib) tx bytes:41874253 (39.9 mib)"

header2 = pkgbuildheader(len(body2))

senddata3 = header1.pack_header+body1.encode()+header2.pack_header+body2.encode()

# 正常資料報

client.send(senddata1)

time.sleep(30)

# 分包測試

client.send(senddata2_1)

time.sleep(1)

client.send(senddata2_2)

time.sleep(3)

# 粘包測試

client.send(senddata3)

time.sleep(3)

client.close()

粘包和分包

socket通訊時會對傳送的位元組資料進行分包和粘包處理,屬於一種socket內部的優化機制。粘包 當傳送的位元組資料報比較小且頻繁傳送時,socket內部會將位元組資料進行粘包處理,既將頻繁傳送的小位元組資料打包成 乙個整包進行傳送,降低記憶體的消耗。分包 當傳送的位元組資料報比較大時,socke...

Socket粘包分包

粘包和分包問題 1.首先什麼是包 包就是每次伺服器向客戶端傳送的資料每傳送乙個訊息都會被打成乙個包傳送到客戶端。客戶端向伺服器端傳送訊息也是一樣的。2.為什麼會有粘包和分包的問題 是因為sockettcp自身的優化機制所導致的。3.什麼是粘包 粘包就是當伺服器端傳送的資料很小的時候又很頻繁的時候,就...

python 網路程式設計 02 粘包

思考 什麼是粘包?同時執行多條命令之後,得到的結果很可能只有一部分,在執行其他命令的時候又接收到之前執行的另外一部分結果,這種顯現就是粘包。例如 send b 123 send b abc recv 4 1234 應該接收123 recv 4 bc 應該接收abc或者傳送的資料量大,一次沒有接收完,...