欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

解決tcp粘包問(wèn)題的辦法有哪些

這篇文章將為大家詳細(xì)講解有關(guān)解決tcp粘包問(wèn)題的辦法有哪些,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。

在安福等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都做網(wǎng)站、成都網(wǎng)站設(shè)計(jì) 網(wǎng)站設(shè)計(jì)制作按需規(guī)劃網(wǎng)站,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站制作,成都全網(wǎng)營(yíng)銷,外貿(mào)網(wǎng)站制作,安福網(wǎng)站建設(shè)費(fèi)用合理。

第一部分:簡(jiǎn)介tcp socket通信的底層原理

原理解析圖:

解決tcp粘包問(wèn)題的辦法有哪些

1 socket通信過(guò)程如圖所示:首先客戶端將發(fā)送內(nèi)容通過(guò)send()方法將內(nèi)容發(fā)送到客戶端計(jì)算機(jī)的內(nèi)核區(qū),然后由操作系統(tǒng)將內(nèi)容通過(guò)底層路徑發(fā)送到服務(wù)器端的內(nèi)核區(qū),然后由服務(wù)器程序通過(guò)recv()方法從服務(wù)器端計(jì)算機(jī)內(nèi)核區(qū)取出數(shù)據(jù)。
2 因此我們可以了解到,send方法并不是直接將內(nèi)容發(fā)送到服務(wù)器端,recv方法也并不是直接將從客戶端發(fā)來(lái)的內(nèi)容接收到服務(wù)器程序內(nèi)存中,而是操作自己機(jī)器的內(nèi)核區(qū)。

第二部分:產(chǎn)生粘包的原因(只針對(duì)tcp)

產(chǎn)生粘包的情況有兩種:

1 1:當(dāng)連續(xù)發(fā)送數(shù)據(jù)時(shí),由于tcp協(xié)議的nagle算法,會(huì)將較小的內(nèi)容拼接成大的內(nèi)容,一次性發(fā)送到服務(wù)器端,因此造成粘包2 3 2:當(dāng)發(fā)送內(nèi)容較大時(shí),由于服務(wù)器端的recv(buffer_size)方法中的buffer_size較小,不能一次性完全接收全部?jī)?nèi)容,因此在下一次請(qǐng)求到達(dá)時(shí),接收的內(nèi)容依然是上一次沒(méi)有完全接收完的內(nèi)容,因此造成粘包現(xiàn)象。

也就是說(shuō):接收方不知道該接收多大的數(shù)據(jù)才算接收完畢,造成粘包。

相關(guān)教程:TCP/IP視頻教程

第三部分:如何解決上述兩種粘包現(xiàn)象?

思路一:對(duì)于第一種粘包產(chǎn)生方式可以在兩次send()直接使用recv()來(lái)阻止連續(xù)發(fā)送的情況發(fā)生。代碼就不用展示了。

思路二:由于產(chǎn)生粘包的原因是接收方的無(wú)邊界接收,因此發(fā)送端可以在發(fā)送數(shù)據(jù)之前向接收端告知發(fā)送內(nèi)容的大小即可。代碼示例如下:

 方式一:分兩次通訊分別傳遞內(nèi)容大小和內(nèi)容

 服務(wù)器端代碼:

# __author__:Kelvin
# date:2019/4/28 21:36
from socket import *
import subprocess

server = socket(AF_INET, SOCK_STREAM)
server.bind(("127.0.0.1", 8000))
server.listen(5)

while True:
    conn, addr = server.accept()
    print("創(chuàng)建了一個(gè)新的連接!")
    while True:
        try:
            data = conn.recv(1024)
            if not data: break
            res = subprocess.Popen(data.decode("utf-8"), shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
            err = res.stderr.read()
            if err:
                cmd_msg = err
            else:
                cmd_msg = res.stdout.read()
            if not cmd_msg: cmd_msg = "action success!".encode("gbk")
            length = len(cmd_msg)
            conn.send(str(length).encode("utf-8"))
            conn.recv(1024)
            conn.send(cmd_msg)
        except Exception as e:
            print(e)
            break

客戶端代碼:

# __author__:Kelvin
# date:2019/4/28 21:36
from socket import *

client = socket(AF_INET, SOCK_STREAM)
client.connect(("127.0.0.1", 8000))
while True:
    inp = input(">>:")
    if not inp: continue
    if inp == "quit": break
    client.send(inp.encode("utf-8"))
    length = int(client.recv(1024).decode("utf-8"))
    client.send("ready!".encode("utf-8"))
    lengthed = 0
    cmd_msg = b""
    while lengthed < length:
        cmd_msg += client.recv(1024)
        lengthed = len(cmd_msg)
    print(cmd_msg.decode("gbk"))

  方式二:一次通訊直接傳遞內(nèi)容大小和內(nèi)容

  服務(wù)器端:

# __author__:Kelvin
# date:2019/4/28 21:36
from socket import *
import subprocess
import struct

server = socket(AF_INET, SOCK_STREAM)
server.bind(("127.0.0.1", 8000))
server.listen(5)

while True:
    conn, addr = server.accept()
    print("創(chuàng)建了一個(gè)新的連接!")
    while True:
        try:
            data = conn.recv(1024)
            if not data: break
            res = subprocess.Popen(data.decode("utf-8"), shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
            err = res.stderr.read()
            if err:
                cmd_msg = err
            else:
                cmd_msg = res.stdout.read()
            if not cmd_msg: cmd_msg = "action success!".encode("gbk")
            length = len(cmd_msg)
            conn.send(struct.pack("i", length))
            conn.send(cmd_msg)
        except Exception as e:
            print(e)
            break

客戶端:

# __author__:Kelvin
# date:2019/4/28 21:36
from socket import *
import struct

client = socket(AF_INET, SOCK_STREAM)
client.connect(("127.0.0.1", 8000))
while True:
    inp = input(">>:")
    if not inp: continue
    if inp == "quit": break
    client.send(inp.encode("utf-8"))
    length = struct.unpack("i",client.recv(4))[0]
    lengthed = 0
    cmd_msg = b""
    while lengthed < length:
        cmd_msg += client.recv(1024)
        lengthed = len(cmd_msg)
    print(cmd_msg.decode("gbk"))

關(guān)于解決tcp粘包問(wèn)題的辦法有哪些就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

網(wǎng)站名稱:解決tcp粘包問(wèn)題的辦法有哪些
本文網(wǎng)址:http://chinadenli.net/article28/jiiicp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站維護(hù)企業(yè)建站、電子商務(wù)、Google品牌網(wǎng)站制作、用戶體驗(yàn)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都seo排名網(wǎng)站優(yōu)化