tcp黏包問題與udp為什么不黏包


  1.先說下subprocess模塊的用法,為了舉個黏包的例子

# 通過一個例子 來認識網絡編程中的一個重要的概念
    # 所有的客戶端執行server端下發的指令,執行完畢后,客戶端將執行結果給返回給服務端


import subprocess   # 這個模塊其實並不好用,這里為了舉例子。調用操作系統的命令模塊


res = subprocess.Popen('dir', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # 執行dir命令,並將標准輸出和錯誤內容裝到了管道中
print('stdout : ', res.stdout.read().decode('gbk')) # 從管道中獲取控制台的內容,windows控制台執行完畢后,得到的是bytes類型的,需要解碼成gbk才可不亂碼顯示,windows控制台返回的是gbk的,所以這里要gbk解碼
print('stderror: ', res.stderr.read().decode('gbk'))

  2.寫一個tcp的server端和client,模擬黏包的現象,tcp端發送windows的命令給client,client接收后執行該命令后,將控制台返回的內容傳輸到server端

  tcpserver.py

# 通過一個例子 來認識網絡編程中的一個重要的概念
    # 所有的客戶端執行server端下發的指令,執行完畢后,客戶端將執行結果給返回給服務端
    # 基於tcp實現遠程執行命令

    # 在server下發windows操作系統命令給client,client執行完畢后返回給sercer

# 出現了黏包現象
    # 數據亂了,數據沒有接收完,下次接收接收到了未接收到的數據等現象

# tcp不會丟包,會黏包。
    # 當傳輸的包很大的時候,tcp協議會將其拆分開進行傳輸。

import socket

sk = socket.socket()

sk.bind(('127.0.0.1', 8080))

sk.listen()

conn, addr = sk.accept()

while True:
    cmd = input('輸入想要客戶端windows系統想要執行的命令:')
    conn.send(cmd.encode('utf-8'))
    msg = conn.recv(1024).decode('utf-8')
    print(msg)

conn.close()
sk.close()

  tcpclient.py

# client接收服務端命令

import socket
import subprocess

sk = socket.socket()

sk.connect(('127.0.0.1', 8080))

while True:
    cmd = sk.recv(1024).decode('utf-8')
    res = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout = 'stdout : ' + res.stdout.read().decode('gbk')
    stderr = 'stderr : ' + res.stderr.read().decode('gbk')
    #print(stdout)
    #print(stderr)
    # res.stdout.read() 為cmd命令執行后返回的結果,返回的是bytes類型數據
    sk.send(stdout.encode('utf-8'))
    sk.send(stderr.encode('utf-8'))

sk.close()

 

  3.udp不黏包,但會丟包例子,與上類似

  udpserver.py

# 測試結果,udp不會黏包,但udp會丟包,數據發送出去后,一旦另一端接收的緩存不夠大,而發送的數據很大時,未接收的數據,會丟棄掉。同時udp大了緩存限制會丟棄包

import socket

sk = socket.socket(type=socket.SOCK_DGRAM)

#sk.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) # 避免服務重啟的時候報address already in use。加上這個解決
sk.bind(('127.0.0.1', 8081))

msg, addr = sk.recvfrom(1024)

while True:
    cmd = input('輸入想要客戶端windows系統想要執行的命令:')
    if cmd == 'q':
        break
    sk.sendto(cmd.encode('utf-8'), addr)
    msg, addr = sk.recvfrom(1024)
    print(msg.decode('utf-8'))

sk.close()

  udpclient.py

# client接收服務端命令

import socket
import subprocess

sk = socket.socket(type=socket.SOCK_DGRAM)

ip_port = ('127.0.0.1', 8081)
sk.sendto(b'hello', ip_port)

while True:
    cmd, addr= sk.recvfrom(1024)
    res = subprocess.Popen(cmd.decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout = 'stdout : ' + res.stdout.read().decode('gbk')
    stderr = 'stderr : ' + res.stderr.read().decode('gbk')
    #print(stdout)
    #print(stderr)
    # res.stdout.read() 為cmd命令執行后返回的結果,返回的是bytes類型數據
    sk.sendto(stdout.encode('utf-8'), ip_port)
    sk.sendto(stderr.encode('utf-8'), ip_port)

sk.close()

 

  4.tcp為什么會黏包

  黏包是這樣出現的

  tcp的拆包機制是類似這樣的

 

  5.udp為什么不會黏包


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM