tcp黏包問題與udp爲何不黏包

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

# 經過一個例子 來認識網絡編程中的一個重要的概念
    # 全部的客戶端執行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.pywindows

# 經過一個例子 來認識網絡編程中的一個重要的概念
    # 全部的客戶端執行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.pysocket

# 測試結果,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.pytcp

# 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爲何會黏包測試

  黏包是這樣出現的spa

  tcp的拆包機制是相似這樣的操作系統

 

  5.udp爲何不會黏包

相關文章
相關標籤/搜索