1. 程式人生 > >04python 黏包(網路程式設計)

04python 黏包(網路程式設計)

什麼叫做黏包?

先寫一個小補充:  
encode()函式、decode()函式:    
encode() 是將資料型別轉換成bytes型別
decode()是將bytes型別轉換成其他型別
encode() 叫做編碼, decode( ) 叫做解碼    

通過一段程式碼來引出黏包現象(基於TCP的網路通訊)
    sever端    

      19           1
import
socket
2
 
         
         
          
          
           3
           
          
         
 
         
         
          
          
           4
           
          
         
sk = socket.socket()
5
sk
.bind(('127.0.0.1', 8080))
6
sk.listen()
7
 
         
         
          
          
           8
           
          
         
conn, addr = sk.accept()
9
 
         
         
          
          
           10
           
          
         
while True:
11
    cmd = input('>>>')
12
    conn.send((cmd.encode('utf-8')))                    # 將輸入的資料轉換層(utf-8)的bytes型別,用於網路傳輸
13
 
         
         
          
          
           14
           
          
         
    ret = conn.recv(1024).decode('utf-8')               # 將接收到的資料(utf-8)的bytes型別資料,解碼成本身的資料型別
15
    print(ret)
16
 
         
         
          
          
           17
           
          
         
 
         
         
          
          
           18
           
          
         
conn.close()
19
sk.close()
          client端    
      20           1
import socket
2
import subprocess
3
 
         
         
          
          
           4
           
          
         
 
         
         
          
          
           5
           
          
         
sk = socket.socket()
6
sk.connect(('127.0.0.1', 8080))
7
while True:
8
    cmd = sk.recv(1024).decode('utf-8')
9
    ret = subprocess.Popen(cmd, shell=True,
10
                           stdout=subprocess.PIPE,
11
                           stderr=subprocess.PIPE)
12
 
         
         
          
          
           13
           
          
         
    std_out = 'stdout :' + (ret.stdout.read()).decode('gbk')
14
    std_err = 'stderr :' + (ret.stderr.read()).decode('gbk')
15
    print(std_out)
16
    print(std_err)
17
    sk.send(std_out.encode('utf-8'))
18
    sk.send(std_err.encode('utf-8'))
19
 
         
         
          
          
           20
           
          
         
sk.close()
             仔細觀察控制檯這個時候會發現基於TCP連線從server端傳送指令時,會接收一些並不完整的資料,在一次從server端傳送指令時,client端會發送上一次斷點的資料給server端,我們把這種現象叫做黏包!          
基於UDP協議的黏包現象(ps:不存在)        
     udp_server     
      20           1
import socket
2
 
         
         
          
          
           3
           
          
         
 
         
         
          
          
           4
           
          
         
sk = socket.socket(type=socket.SOCK_DGRAM)
5
sk.bind(('127.0.0.1', 8091))
6
 
         
         
          
          
           7
           
          
         
msg, addr = sk.recvfrom(1024)
8
 
         
         
          
          
           9
           
          
         
while True:
10
    cmd = input('>>>')
11
    if cmd == 'q':
12
        break
13
    sk.sendto(cmd.encode('utf-8'), addr)
14
    msg, addr = sk.recvfrom(1024)                            # 兩次傳送、兩次接收
15
    print(msg.decode('utf-8'))
16
    msg, addr = sk.recvfrom(1024)
17
    print(msg.decode('utf-8'))
18
 
         
         
          
          
           19
           
          
         
 
         
         
          
          
           20
           
          
         
sk.close()
          udp_client    
      x           1
import socket
2
import subprocess
3
 
         
         
          
          
           4
           
          
         
 
         
         
          
          
           5
           
          
         
sk = socket.socket(type=socket.SOCK_DGRAM)
6
addr = ('127.0.0.1', 8091)
7
 
         
         
          
          
           8
           
          
         
sk.sendto('吃了嗎?'.encode('utf-8'), addr)
9
 
         
         
          
          
           10
           
          
         
while True:
11
    cmd, addr = sk.recvfrom(1024)
12
    ret = subprocess.Popen(cmd.decode('gbk'),                   # 這裡轉碼與解碼的方式前後不一致,但傳送過來的資料是英文。所以無妨!
13
                           shell=True,
14
                           stdout=subprocess.PIPE,
15
                           stderr=subprocess.PIPE
16
                           )
17
    std_out = 'stdout: ' + (ret.stdout.read()).decode('gbk')
18
    std_err = 'stderr: ' + (ret.stderr.read()).decode('gbk')
19
    print(std_out)
20
    print(std_err)
21
 
         
         
          
          
           22
           
          
         
    sk.sendto(std_out.encode('utf-8'), addr)
23
    sk.sendto(std_err.encode('utf-8'), addr)
24
 
         
         
          
          
           25
           
          
         
sk.close()
26