欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Python學習日記(三十一) 黏包問題

系統 2102 0
            
              import
            
            
               subprocess

res 
            
            = subprocess.Popen(
            
              '
            
            
              dir
            
            
              '
            
            ,shell=True,stdout=subprocess.PIPE,stderr=
            
              subprocess.PIPE)

            
            
              print
            
            (
            
              '
            
            
              Stdout:
            
            
              '
            
            ,res.stdout.read().decode(
            
              '
            
            
              gbk
            
            
              '
            
            
              ))

            
            
              print
            
            (
            
              '
            
            
              Stderr:
            
            
              '
            
            ,res.stderr.read().decode(
            
              '
            
            
              gbk
            
            
              '
            
            ))
          

PIPE把輸出的東西裝到一個'水管'里,如果在windows中的編碼格式是gbk,執行結果:

            
              Stdout:  驅動器 C 中的卷是 系統
 卷的序列號是 85C0
            
            -
            
              669A

 C:\Users\Administrator\PycharmProjects\Internet_program 的目錄


            
            2019/09/16  13:48    
            
              
                          .

              
              2019/09/16  13:48    
              
                
                            ..

                
                2019/09/16  13:47    
                
                  
                              .idea

                  
                  2019/09/16  13:46                21
                  
                     Client1.py

                  
                  2019/09/16  13:42
                  
                                     0 Client2.py

                  
                  2019/09/16  13:48               207
                  
                     Sever1.py

                  
                  2019/09/16  01:41                70
                  
                     time_test.py

                  
                  2019/09/14  23:51    
                  
                    
                                venv
               
                    
                    4 個文件            298
                    
                       字節
               
                    
                    4 個目錄 45,863,636,992
                    
                       可用字節

Stderr: 
                    
                  
                
              
            
          

在這里也可以使用os.popen()但是它會不管正確和錯誤的結果都放在一起,而用subprocess能夠分別拿到正確和錯誤的信息

?

基于TCP實現的黏包

Sever:

            
              import
            
            
               socket
sk 
            
            =
            
               socket.socket()
sk.bind((
            
            
              '
            
            
              127.0.0.1
            
            
              '
            
            ,8092
            
              ))
sk.listen()
conn,addr 
            
            =
            
               sk.accept()

            
            
              while
            
            
               True:
    cmd 
            
            = input(
            
              '
            
            
              <<<
            
            
              '
            
            
              )
    conn.send(cmd.encode(
            
            
              '
            
            
              gbk
            
            
              '
            
            
              ))
    ret 
            
            = conn.recv(1024).decode(
            
              '
            
            
              gbk
            
            
              '
            
            
              )
    
            
            
              print
            
            
              (ret)
conn.close()
sk.close()
            
          

Client:

            
              import
            
            
               socket

            
            
              import
            
            
               subprocess
sk 
            
            =
            
               socket.socket()
sk.connect((
            
            
              '
            
            
              127.0.0.1
            
            
              '
            
            ,8092
            
              ))

            
            
              while
            
            
               True:
    cmd 
            
            = sk.recv(1024).decode(
            
              '
            
            
              gbk
            
            
              '
            
            
              )
    ret 
            
            = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=
            
              subprocess.PIPE)
    std_out 
            
            = 
            
              '
            
            
              stdout:
            
            
              '
            
             + (ret.stdout.read()).decode(
            
              '
            
            
              gbk
            
            
              '
            
            
              )
    std_err 
            
            = 
            
              '
            
            
              stderr:
            
            
              '
            
             + (ret.stderr.read()).decode(
            
              '
            
            
              gbk
            
            
              '
            
            
              )
    
            
            
              print
            
            
              (std_out)
    
            
            
              print
            
            
              (std_err)
    sk.send(std_out.encode(
            
            
              '
            
            
              gbk
            
            
              '
            
            
              ))
    sk.send(std_err.encode(
            
            
              '
            
            
              gbk
            
            
              '
            
            
              ))
sk.close()
            
          

執行結果:

Sever:

            <<<
            
              dir;ls
stdout: 驅動器 C 中的卷是 系統
 卷的序列號是 85C0
            
            -
            
              669A

 C:\Users\Administrator\PycharmProjects\Internet_program 的目錄



            
            <<<
            
              ipconfig
stderr:找不到文件


            
            <<<
          

Client:

            
              stdout: 驅動器 C 中的卷是 系統
 卷的序列號是 85C0
            
            -
            
              669A

 C:\Users\Administrator\PycharmProjects\Internet_program 的目錄


stderr:找不到文件

stdout:
Windows IP 配置


以太網適配器 Bluetooth 網絡連接 
            
            2
            
              :

   媒體狀態  . . . . . . . . . . . . : 媒體已斷開
   連接特定的 DNS 后綴 . . . . . . . : 

以太網適配器 本地連接:

   媒體狀態  . . . . . . . . . . . . : 媒體已斷開
   連接特定的 DNS 后綴 . . . . . . . : 

無線局域網適配器 無線網絡連接:

   連接特定的 DNS 后綴 . . . . . . . : 
   本地鏈接 IPv6 地址. . . . . . . . : fe80::8c6:36a9:6fa6:
            
            8018%14
            
              
   IPv4 地址 . . . . . . . . . . . . : 
            
            192.168.43.216
            
              
   子網掩碼  . . . . . . . . . . . . : 
            
            255.255.255.0
            
              
   默認網關. . . . . . . . . . . . . : 
            
            192.168.43.1
            
              

隧道適配器 本地連接
            
            * 3
            
              :

   媒體狀態  . . . . . . . . . . . . : 媒體已斷開
   連接特定的 DNS 后綴 . . . . . . . : 

stderr:
            
          

當我們在sever端輸入dir;ls命令時,只有stdout的結果跑出來,而當我們輸入ipconfig這個命令時,系統將上一次dir;ls未執行完的stderr的結果給跑出來。像這樣沒有接受完全或者接受多了的就是黏包現象。

TCP會有黏包現象但是它不丟包。

?

基于UDP實現的黏包

Sever:

            
              import
            
            
               socket
sk 
            
            = socket.socket(type=
            
              socket.SOCK_DGRAM)
sk.bind((
            
            
              '
            
            
              127.0.0.1
            
            
              '
            
            ,8092
            
              ))
msg,addr 
            
            = sk.recvfrom(10240
            
              )


            
            
              while
            
             1
            
              :
    cmd 
            
            = input(
            
              '
            
            
              <<<
            
            
              '
            
            
              )
    
            
            
              if
            
             cmd == 
            
              '
            
            
              q
            
            
              '
            
            
              :
        
            
            
              break
            
            
              
    sk.sendto(cmd.encode(
            
            
              '
            
            
              gbk
            
            
              '
            
            
              ),addr)
    msg,addr 
            
            = sk.recvfrom(10240
            
              )
    
            
            
              print
            
            (msg.decode(
            
              '
            
            
              gbk
            
            
              '
            
            
              ))

sk.close()
            
          

Client:

            
              import
            
            
               socket

            
            
              import
            
            
               subprocess
sk 
            
            = socket.socket(type=
            
              socket.SOCK_DGRAM)
addr 
            
            = (
            
              '
            
            
              127.0.0.1
            
            
              '
            
            ,8092
            
              )
sk.sendto(
            
            
              '
            
            
              Start
            
            
              '
            
            .encode(
            
              '
            
            
              utf-8
            
            
              '
            
            
              ),addr)

            
            
              while
            
             1
            
              :
    cmd,addr 
            
            = sk.recvfrom(10240
            
              )
    ret 
            
            = subprocess.Popen(cmd.decode(
            
              '
            
            
              gbk
            
            
              '
            
            ),shell=True,stderr=subprocess.PIPE,stdout=
            
              subprocess.PIPE)
    std_out 
            
            = 
            
              '
            
            
              Stdout:
            
            
              '
            
             + (ret.stdout.read()).decode(
            
              '
            
            
              gbk
            
            
              '
            
            
              )
    std_err 
            
            = 
            
              '
            
            
              Stderr:
            
            
              '
            
             + (ret.stderr.read()).decode(
            
              '
            
            
              gbk
            
            
              '
            
            
              )
    
            
            
              print
            
            
              (std_out)
    
            
            
              print
            
            
              (std_err)
    sk.sendto(std_out.encode(
            
            
              '
            
            
              gbk
            
            
              '
            
            
              ),addr)
    sk.sendto(std_err.encode(
            
            
              '
            
            
              gbk
            
            
              '
            
            
              ),addr)
sk.close()
            
          

執行結果:

Sever:

            <<<
            
              dir;ls
Stdout: 驅動器 C 中的卷是 系統
 卷的序列號是 85C0
            
            -
            
              669A

 C:\Users\Administrator\PycharmProjects\Internet_program 的目錄



            
            <<<
            
              dir
Stderr:找不到文件


            
            <<<
            
              ipconfig
Stdout: 驅動器 C 中的卷是 系統
 卷的序列號是 85C0
            
            -
            
              669A

 C:\Users\Administrator\PycharmProjects\Internet_program 的目錄


            
            2019/09/16  14:43    
            
              
                          .

              
              2019/09/16  14:43    
              
                
                            ..

                
                2019/09/16  14:37    
                
                  
                              .idea

                  
                  2019/09/16  14:43               553
                  
                     Client1.py

                  
                  2019/09/16  13:42
                  
                                     0 Client2.py

                  
                  2019/09/16  14:43               306
                  
                     Sever1.py

                  
                  2019/09/16  01:41                70
                  
                     time_test.py

                  
                  2019/09/14  23:51    
                  
                    
                                venv
               
                    
                    4 個文件            929
                    
                       字節
               
                    
                    4 個目錄 45,855,449,088
                    
                       可用字節


                    
                    <<<
                    
                      pwd
Stderr:

                    
                    <<<
                    
                      ip
Stdout:
Windows IP 配置


以太網適配器 Bluetooth 網絡連接 
                    
                    2
                    
                      :

   媒體狀態  . . . . . . . . . . . . : 媒體已斷開
   連接特定的 DNS 后綴 . . . . . . . : 

以太網適配器 本地連接:

   媒體狀態  . . . . . . . . . . . . : 媒體已斷開
   連接特定的 DNS 后綴 . . . . . . . : 

無線局域網適配器 無線網絡連接:

   連接特定的 DNS 后綴 . . . . . . . : 
   本地鏈接 IPv6 地址. . . . . . . . : fe80::8c6:36a9:6fa6:
                    
                    8018%14
                    
                      
   IPv4 地址 . . . . . . . . . . . . : 
                    
                    192.168.43.216
                    
                      
   子網掩碼  . . . . . . . . . . . . : 
                    
                    255.255.255.0
                    
                      
   默認網關. . . . . . . . . . . . . : 
                    
                    192.168.43.1
                    
                      

隧道適配器 本地連接
                    
                    * 3
                    
                      :

   媒體狀態  . . . . . . . . . . . . : 媒體已斷開
   連接特定的 DNS 后綴 . . . . . . . : 


                    
                    <<<
                  
                
              
            
          

Client:

            
              Stdout: 驅動器 C 中的卷是 系統
 卷的序列號是 85C0
            
            -
            
              669A

 C:\Users\Administrator\PycharmProjects\Internet_program 的目錄


Stderr:找不到文件

Stdout: 驅動器 C 中的卷是 系統
 卷的序列號是 85C0
            
            -
            
              669A

 C:\Users\Administrator\PycharmProjects\Internet_program 的目錄


            
            2019/09/16  14:43    
            
              
                          .

              
              2019/09/16  14:43    
              
                
                            ..

                
                2019/09/16  14:37    
                
                  
                              .idea

                  
                  2019/09/16  14:43               553
                  
                     Client1.py

                  
                  2019/09/16  13:42
                  
                                     0 Client2.py

                  
                  2019/09/16  14:43               306
                  
                     Sever1.py

                  
                  2019/09/16  01:41                70
                  
                     time_test.py

                  
                  2019/09/14  23:51    
                  
                    
                                venv
               
                    
                    4 個文件            929
                    
                       字節
               
                    
                    4 個目錄 45,855,449,088
                    
                       可用字節

Stderr:
Stdout:
Windows IP 配置


以太網適配器 Bluetooth 網絡連接 
                    
                    2
                    
                      :

   媒體狀態  . . . . . . . . . . . . : 媒體已斷開
   連接特定的 DNS 后綴 . . . . . . . : 

以太網適配器 本地連接:

   媒體狀態  . . . . . . . . . . . . : 媒體已斷開
   連接特定的 DNS 后綴 . . . . . . . : 

無線局域網適配器 無線網絡連接:

   連接特定的 DNS 后綴 . . . . . . . : 
   本地鏈接 IPv6 地址. . . . . . . . : fe80::8c6:36a9:6fa6:
                    
                    8018%14
                    
                      
   IPv4 地址 . . . . . . . . . . . . : 
                    
                    192.168.43.216
                    
                      
   子網掩碼  . . . . . . . . . . . . : 
                    
                    255.255.255.0
                    
                      
   默認網關. . . . . . . . . . . . . : 
                    
                    192.168.43.1
                    
                      

隧道適配器 本地連接
                    
                    * 3
                    
                      :

   媒體狀態  . . . . . . . . . . . . : 媒體已斷開
   連接特定的 DNS 后綴 . . . . . . . : 

Stderr:
Stdout:
Stderr:
                    
                    
                      '
                    
                    
                      pwd
                    
                    
                      '
                    
                    
                       不是內部或外部命令,也不是可運行的程序
或批處理文件。

Stdout:
Stderr:
                    
                    
                      '
                    
                    
                      ip
                    
                    
                      '
                    
                    
                       不是內部或外部命令,也不是可運行的程序
或批處理文件。
                    
                  
                
              
            
          

可以看出UDP不會有黏包現象,會產生丟包現象,沒發完就不發了,不完整也不可靠。

?

黏包成因

TCP協議的數據傳送

拆包機制

當發送端緩沖區的長度大于網卡的MTU時,TCP會將這次發送的數據拆成幾個數據包發送出去。MTU是Maximum Transmission Unit的縮寫,意思是網絡上傳送最大數據包,MTU是字節單位,大部分網絡設備的MTU都是1500. 如果本機的MTU比網關的MTU大,大的數據包就會被拆開來傳送,這樣會產生很多數據包碎片,增加丟包率,降低網絡速度。

在正常情況下它的拆包可理解為:

Python學習日記(三十一) 黏包問題_第1張圖片

面向流的通信特點和Nagle算法

TCP(transport control protocol,傳輸控制協議),是面向連接的,面向流的,提供高可靠性的服務。收發兩端(客戶端和服務端)都要有一一成對的socket,因此發送端為了將多個發往接收端的包,更有效地發往對方,使用了優化算法(Nagle算法),將多次間隔較小且數據量小的數據,合并成一個大的數據塊,然后進行封包。這樣接收端就難于分辨出來了,必須提供科學的拆包機制。即面向流的通信是無消息保護邊界的。

對于空消息:TCP是基于數據流的,于是收發消息不能為空,這就需要在客戶端和服務端都添加空消息的處理機制,防止程序卡住,而UDP協議是基于數據報的,即便是你輸入的是空內容(直接回車),也可以被發送,UDP協議會幫你封裝上消息然后發出去。

可靠黏包的TCP協議:TCP協議數據不會丟,沒有收完包,就會下次接收,會繼續上次繼續接受。

基于tcp協議特點的黏包現象成因

Python學習日記(三十一) 黏包問題_第2張圖片

當我們在socket服務端發送值1、2,然后根據優化算法,它會把1先放到這個緩存當中等一等,然后再把2一起封裝起來,然后再發出去,因此我們看到的就是黏包現象

這種現象的表面現象是兩個send太近且發送的消息太短

發送端可以使1K1K地發送數據,而接收端的應用程序可以兩K兩K地提走數據,當然也有可能一次提走3K或6K數據,或者一次只提走幾個字節的數據。也就是說,應用程序所看到的數據是一個整體,或者說是一個流(stream),一條消息有多少字節對應程序是不可見的,因此TCP協議是面向流的協議,這也是容易出現黏包問題的原因。而UDP協議是面向消息的協議,每個UDP段都是一條消息,應用程序必須以消息單位提取數據,不能一次提取任意字節的數據,這一點和TCP是很不同的。

?

解決黏包的方法

解決方案一:

Sever:

            
              import
            
            
               socket
sk 
            
            =
            
               socket.socket()
sk.bind((
            
            
              '
            
            
              127.0.0.1
            
            
              '
            
            ,8080
            
              ))
sk.listen()
conn,addr 
            
            =
            
               sk.accept()


            
            
              while
            
            
               True:
    cmd 
            
            = input(
            
              '
            
            
              <<<
            
            
              '
            
            
              )
    
            
            
              if
            
             cmd == 
            
              '
            
            
              q
            
            
              '
            
            
              :
        conn.send(b
            
            
              '
            
            
              q
            
            
              '
            
            
              )
        
            
            
              break
            
            
              
    conn.send(cmd.encode(
            
            
              '
            
            
              gbk
            
            
              '
            
            
              ))
    num 
            
            = conn.recv(1024).decode(
            
              '
            
            
              utf-8
            
            
              '
            
            
              )
    conn.send(b
            
            
              '
            
            
              ok
            
            
              '
            
            
              )
    res 
            
            = conn.recv(int(num)).decode(
            
              '
            
            
              gbk
            
            
              '
            
            
              )
    
            
            
              print
            
            
              (res)

conn.close()
sk.close()
            
          

Client:

            
              import
            
            
               socket

            
            
              import
            
            
               subprocess

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

            
            
              while
            
            
               True:
    cmd 
            
            = sk.recv(1024).decode(
            
              '
            
            
              gbk
            
            
              '
            
            
              )
    
            
            
              if
            
             cmd == 
            
              '
            
            
              q
            
            
              '
            
            
              :
        
            
            
              break
            
            
              
    res 
            
            = subprocess.Popen(cmd,shell=
            
              True,
                           stdout
            
            =
            
              subprocess.PIPE,
                           stderr
            
            =
            
              subprocess.PIPE)
    std_out 
            
            =
            
               res.stdout.read()
    std_err 
            
            =
            
               res.stderr.read()
    sk.send(str(len(std_out) 
            
            + len(std_err)).encode(
            
              '
            
            
              utf-8
            
            
              '
            
            
              ))
    sk.recv(
            
            1024
            
              )
    
            
            
              print
            
            (
            
              '
            
            
              Stdout:
            
            
              '
            
             + std_out.decode(
            
              '
            
            
              gbk
            
            
              '
            
            
              ))
    
            
            
              print
            
            (
            
              '
            
            
              Stderr:
            
            
              '
            
             + std_err.decode(
            
              '
            
            
              gbk
            
            
              '
            
            
              ))
    sk.send(std_out)
    sk.send(std_err)

sk.close()
            
          

執行結果:

Sever:

            <<<
            
              dir
 驅動器 C 中的卷是 系統
 卷的序列號是 85C0
            
            -
            
              669A

 C:\Users\Administrator\PycharmProjects\Internet_program 的目錄


            
            2019/09/17  15:33    
            
              
                          .

              
              2019/09/17  15:33    
              
                
                            ..

                
                2019/09/17  15:31    
                
                  
                              .idea

                  
                  2019/09/17  15:33               623
                  
                     Client1.py

                  
                  2019/09/16  13:42
                  
                                     0 Client2.py

                  
                  2019/09/17  15:21               389
                  
                     Sever1.py

                  
                  2019/09/16  01:41                70
                  
                     time_test.py

                  
                  2019/09/14  23:51    
                  
                    
                                venv
               
                    
                    4 個文件          1,082
                    
                       字節
               
                    
                    4 個目錄 45,031,833,600
                    
                       可用字節


                    
                    <<<
                    
                      ls

                    
                    
                      '
                    
                    
                      ls
                    
                    
                      '
                    
                    
                       不是內部或外部命令,也不是可運行的程序
或批處理文件。


                    
                    <<<
                    
                      ipconfig

Windows IP 配置


以太網適配器 Bluetooth 網絡連接 
                    
                    2
                    
                      :

   媒體狀態  . . . . . . . . . . . . : 媒體已斷開
   連接特定的 DNS 后綴 . . . . . . . : 

以太網適配器 本地連接:

   媒體狀態  . . . . . . . . . . . . : 媒體已斷開
   連接特定的 DNS 后綴 . . . . . . . : 

無線局域網適配器 無線網絡連接:

   連接特定的 DNS 后綴 . . . . . . . : 
   本地鏈接 IPv6 地址. . . . . . . . : fe80::8c6:36a9:6fa6:
                    
                    8018%14
                    
                      
   IPv4 地址 . . . . . . . . . . . . : 
                    
                    192.168.43.216
                    
                      
   子網掩碼  . . . . . . . . . . . . : 
                    
                    255.255.255.0
                    
                      
   默認網關. . . . . . . . . . . . . : 
                    
                    192.168.43.1
                    
                      

隧道適配器 本地連接
                    
                    * 3
                    
                      :

   媒體狀態  . . . . . . . . . . . . : 媒體已斷開
   連接特定的 DNS 后綴 . . . . . . . : 


                    
                    <<<
                  
                
              
            
          

Client:

            
              Stdout: 驅動器 C 中的卷是 系統
 卷的序列號是 85C0
            
            -
            
              669A

 C:\Users\Administrator\PycharmProjects\Internet_program 的目錄


            
            2019/09/17  15:33    
            
              
                          .

              
              2019/09/17  15:33    
              
                
                            ..

                
                2019/09/17  15:31    
                
                  
                              .idea

                  
                  2019/09/17  15:33               623
                  
                     Client1.py

                  
                  2019/09/16  13:42
                  
                                     0 Client2.py

                  
                  2019/09/17  15:21               389
                  
                     Sever1.py

                  
                  2019/09/16  01:41                70
                  
                     time_test.py

                  
                  2019/09/14  23:51    
                  
                    
                                venv
               
                    
                    4 個文件          1,082
                    
                       字節
               
                    
                    4 個目錄 45,031,833,600
                    
                       可用字節

Stderr:
Stdout:
Stderr:
                    
                    
                      '
                    
                    
                      ls
                    
                    
                      '
                    
                    
                       不是內部或外部命令,也不是可運行的程序
或批處理文件。

Stdout:
Windows IP 配置


以太網適配器 Bluetooth 網絡連接 
                    
                    2
                    
                      :

   媒體狀態  . . . . . . . . . . . . : 媒體已斷開
   連接特定的 DNS 后綴 . . . . . . . : 

以太網適配器 本地連接:

   媒體狀態  . . . . . . . . . . . . : 媒體已斷開
   連接特定的 DNS 后綴 . . . . . . . : 

無線局域網適配器 無線網絡連接:

   連接特定的 DNS 后綴 . . . . . . . : 
   本地鏈接 IPv6 地址. . . . . . . . : fe80::8c6:36a9:6fa6:
                    
                    8018%14
                    
                      
   IPv4 地址 . . . . . . . . . . . . : 
                    
                    192.168.43.216
                    
                      
   子網掩碼  . . . . . . . . . . . . : 
                    
                    255.255.255.0
                    
                      
   默認網關. . . . . . . . . . . . . : 
                    
                    192.168.43.1
                    
                      

隧道適配器 本地連接
                    
                    * 3
                    
                      :

   媒體狀態  . . . . . . . . . . . . : 媒體已斷開
   連接特定的 DNS 后綴 . . . . . . . : 

Stderr:
                    
                  
                
              
            
          

這種寫法的好處就是能確定Sever到底要接受多少數據,不好的地方就是多了一次交互

解決方案二: 使用struct模塊

用struct模塊我們能把一個數據類型轉換成固定長度的bytes

Python學習日記(三十一) 黏包問題_第3張圖片

這里以數字類型舉例,'i'代表int類型:

            
              import
            
            
               struct

            
            
              print
            
            (struct.pack(
            
              '
            
            
              i
            
            
              '
            
            ,2048),len(struct.pack(
            
              '
            
            
              i
            
            
              '
            
            ,2048)))         
            
              #
            
            
              b'\x00\x08\x00\x00'    4
            
            
              print
            
            (struct.pack(
            
              '
            
            
              i
            
            
              '
            
            ,204800),len(struct.pack(
            
              '
            
            
              i
            
            
              '
            
            ,204800)))     
            
              #
            
            
              b'\x00 \x03\x00'       4
            
            
              print
            
            (struct.pack(
            
              '
            
            
              i
            
            
              '
            
            ,2048000),len(struct.pack(
            
              '
            
            
              i
            
            
              '
            
            ,2048000)))   
            
              #
            
            
              b'\x00@\x1f\x00'       4
            
          

當后面的數值戳過一定范圍的時候程序就會報錯

Sever:

            
              import
            
            
               socket

            
            
              import
            
            
               struct
sk 
            
            =
            
               socket.socket()
sk.bind((
            
            
              '
            
            
              127.0.0.1
            
            
              '
            
            ,8080
            
              ))
sk.listen()
conn,addr 
            
            =
            
               sk.accept()


            
            
              while
            
            
               True:
    cmd 
            
            = input(
            
              '
            
            
              <<<
            
            
              '
            
            
              )
    
            
            
              if
            
             cmd == 
            
              '
            
            
              q
            
            
              '
            
            
              :
        conn.send(b
            
            
              '
            
            
              q
            
            
              '
            
            
              )
        
            
            
              break
            
            
              
    conn.send(cmd.encode(
            
            
              '
            
            
              gbk
            
            
              '
            
            
              ))
    num 
            
            = conn.recv(4
            
              )
    num 
            
            = struct.unpack(
            
              '
            
            
              i
            
            
              '
            
            
              ,num)[0]
    res 
            
            = conn.recv(int(num)).decode(
            
              '
            
            
              gbk
            
            
              '
            
            
              )
    
            
            
              print
            
            
              (res)

conn.close()
sk.close()
            
          

Client:

            
              import
            
            
               socket

            
            
              import
            
            
               subprocess

            
            
              import
            
            
               struct

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

            
            
              while
            
            
               True:
    cmd 
            
            = sk.recv(1024).decode(
            
              '
            
            
              gbk
            
            
              '
            
            
              )
    
            
            
              if
            
             cmd == 
            
              '
            
            
              q
            
            
              '
            
            
              :
        
            
            
              break
            
            
              
    res 
            
            = subprocess.Popen(cmd,shell=
            
              True,
                           stdout
            
            =
            
              subprocess.PIPE,
                           stderr
            
            =
            
              subprocess.PIPE)
    std_out 
            
            =
            
               res.stdout.read()
    std_err 
            
            =
            
               res.stderr.read()
    len_num 
            
            = len(std_out) +
            
               len(std_err)
    num_by 
            
            = struct.pack(
            
              '
            
            
              i
            
            
              '
            
            
              ,len_num)
    
            
            
              print
            
            (
            
              '
            
            
              Stdout:
            
            
              '
            
             + std_out.decode(
            
              '
            
            
              gbk
            
            
              '
            
            
              ))
    
            
            
              print
            
            (
            
              '
            
            
              Stderr:
            
            
              '
            
             + std_err.decode(
            
              '
            
            
              gbk
            
            
              '
            
            
              ))
    sk.send(num_by)
    sk.send(std_out)
    sk.send(std_err)

sk.close()
            
          

執行結果:

              <<<
              
                dir
 驅動器 C 中的卷是 系統
 卷的序列號是 85C0
              
              -
              
                669A

 C:\Users\Administrator\PycharmProjects\Internet_program 的目錄


              
              2019/09/17  16:25    
              
                
                            .

                
                2019/09/17  16:25    
                
                  
                              ..

                  
                  2019/09/17  16:23    
                  
                    
                                .idea

                    
                    2019/09/17  16:25               659
                    
                       Client1.py

                    
                    2019/09/16  13:42
                    
                                       0 Client2.py

                    
                    2019/09/17  16:22               400
                    
                       Sever1.py

                    
                    2019/09/17  16:08               288
                    
                       time_test.py

                    
                    2019/09/14  23:51    
                    
                      
                                  venv
               
                      
                      4 個文件          1,347
                      
                         字節
               
                      
                      4 個目錄 45,025,951,744
                      
                         可用字節


                      
                      <<<
                      
                        configip

                      
                      
                        '
                      
                      
                        configip
                      
                      
                        '
                      
                      
                         不是內部或外部命令,也不是可運行的程序
或批處理文件。


                      
                      <<<
                      
                        ipconfig

Windows IP 配置


以太網適配器 Bluetooth 網絡連接 
                      
                      2
                      
                        :

   媒體狀態  . . . . . . . . . . . . : 媒體已斷開
   連接特定的 DNS 后綴 . . . . . . . : 

以太網適配器 本地連接:

   媒體狀態  . . . . . . . . . . . . : 媒體已斷開
   連接特定的 DNS 后綴 . . . . . . . : 

無線局域網適配器 無線網絡連接:

   連接特定的 DNS 后綴 . . . . . . . : 
   本地鏈接 IPv6 地址. . . . . . . . : fe80::8c6:36a9:6fa6:
                      
                      8018%14
                      
                        
   IPv4 地址 . . . . . . . . . . . . : 
                      
                      192.168.43.216
                      
                        
   子網掩碼  . . . . . . . . . . . . : 
                      
                      255.255.255.0
                      
                        
   默認網關. . . . . . . . . . . . . : 
                      
                      192.168.43.1
                      
                        

隧道適配器 本地連接
                      
                      * 3
                      
                        :

   媒體狀態  . . . . . . . . . . . . : 媒體已斷開
   連接特定的 DNS 后綴 . . . . . . . : 


                      
                      <<<
                    
                  
                
              
            
Sever執行結果
              
                Stdout: 驅動器 C 中的卷是 系統
 卷的序列號是 85C0
              
              -
              
                669A

 C:\Users\Administrator\PycharmProjects\Internet_program 的目錄


              
              2019/09/17  16:25    
              
                
                            .

                
                2019/09/17  16:25    
                
                  
                              ..

                  
                  2019/09/17  16:23    
                  
                    
                                .idea

                    
                    2019/09/17  16:25               659
                    
                       Client1.py

                    
                    2019/09/16  13:42
                    
                                       0 Client2.py

                    
                    2019/09/17  16:22               400
                    
                       Sever1.py

                    
                    2019/09/17  16:08               288
                    
                       time_test.py

                    
                    2019/09/14  23:51    
                    
                      
                                  venv
               
                      
                      4 個文件          1,347
                      
                         字節
               
                      
                      4 個目錄 45,025,951,744
                      
                         可用字節

Stderr:
Stdout:
Stderr:
                      
                      
                        '
                      
                      
                        configip
                      
                      
                        '
                      
                      
                         不是內部或外部命令,也不是可運行的程序
或批處理文件。

Stdout:
Windows IP 配置


以太網適配器 Bluetooth 網絡連接 
                      
                      2
                      
                        :

   媒體狀態  . . . . . . . . . . . . : 媒體已斷開
   連接特定的 DNS 后綴 . . . . . . . : 

以太網適配器 本地連接:

   媒體狀態  . . . . . . . . . . . . : 媒體已斷開
   連接特定的 DNS 后綴 . . . . . . . : 

無線局域網適配器 無線網絡連接:

   連接特定的 DNS 后綴 . . . . . . . : 
   本地鏈接 IPv6 地址. . . . . . . . : fe80::8c6:36a9:6fa6:
                      
                      8018%14
                      
                        
   IPv4 地址 . . . . . . . . . . . . : 
                      
                      192.168.43.216
                      
                        
   子網掩碼  . . . . . . . . . . . . : 
                      
                      255.255.255.0
                      
                        
   默認網關. . . . . . . . . . . . . : 
                      
                      192.168.43.1
                      
                        

隧道適配器 本地連接
                      
                      * 3
                      
                        :

   媒體狀態  . . . . . . . . . . . . : 媒體已斷開
   連接特定的 DNS 后綴 . . . . . . . : 

Stderr:
                      
                    
                  
                
              
            
Client執行結果

實現一個大文件的傳輸和下載

當我們在網絡上傳輸所有數據時,這些數據都叫數據包,數據包里的所有數據都叫報文,報文里不止有你的數據還有IP地址、MAC地址、端口號等,所有的報文都有報頭,這是由協議規定的。所有在網絡上傳播數據包的協議里都有一個報頭。什么時候需要自己定制報文?比如說復雜的應用上就會應用到、傳輸文件的時候(文件名、文件大小、文件類型、存儲路徑等)...

其實在網絡傳輸的過程當中處處有協議,協議就是一堆報頭和報文(都由字節組成)。

Sever:

            
              import
            
            
               socket

            
            
              import
            
            
               struct

            
            
              import
            
            
               json
buffer 
            
            = 1024
            
              
sk 
            
            =
            
               socket.socket()
sk.bind((
            
            
              '
            
            
              127.0.0.1
            
            
              '
            
            ,8080
            
              ))
sk.listen()

conn,addr 
            
            =
            
               sk.accept()

head_len 
            
            = conn.recv(4
            
              )
struct.unpack(
            
            
              '
            
            
              i
            
            
              '
            
            
              ,head_len)[0]
json_head 
            
            = conn.recv(head_len).decode(
            
              '
            
            
              utf-8
            
            
              '
            
            
              )
head 
            
            =
            
               json.loads(json_head)
file_size 
            
            = head[
            
              '
            
            
              fileSize
            
            
              '
            
            
              ]

with open(r
            
            
              '
            
            
              dir\%s
            
            
              '
            
            %head[
            
              '
            
            
              fileName
            
            
              '
            
            ],
            
              '
            
            
              wb
            
            
              '
            
            
              ) as f:
    
            
            
              while
            
            
               file_size:
        
            
            
              if
            
             file_size >=
            
               buffer:
            content 
            
            =
            
               conn.recv(buffer)
            f.write(content)
            file_size 
            
            -=
            
               buffer
        
            
            
              else
            
            
              :
            content 
            
            =
            
               conn.recv(buffer)
            f.write(content)
            
            
            
              break
            
            
              
conn.close()
sk.close()
            
          

Client:

            
              import
            
            
               socket

            
            
              import
            
            
               struct

            
            
              import
            
            
               os

            
            
              import
            
            
               json

sk 
            
            =
            
               socket.socket()
sk.connect((
            
            
              '
            
            
              127.0.0.1
            
            
              '
            
            ,8080
            
              ))
buffer 
            
            = 1024
            
              
head 
            
            = {
            
              '
            
            
              filePath
            
            
              '
            
             : r
            
              '
            
            
              C:\Users\Administrator\Desktop\專題\海報資料夾\專題海報
            
            
              '
            
            
              ,
        
            
            
              '
            
            
              fileName
            
            
              '
            
             : r
            
              '
            
            
              專題海報
            
            
              '
            
            
              ,
        
            
            
              '
            
            
              fileSize
            
            
              '
            
            
               : None}
file_path 
            
            = os.path.join(head[
            
              '
            
            
              filePath
            
            
              '
            
            ],head[
            
              '
            
            
              fileName
            
            
              '
            
            
              ])
file_size 
            
            =
            
               os.path.getsize(file_path)

head[
            
            
              '
            
            
              fileSize
            
            
              '
            
            ] =
            
               file_size
json_head 
            
            = json.dumps(head)                            
            
              #
            
            
              字典轉成字典
            
            
bytes_head = json_head.encode(
            
              '
            
            
              utf-8
            
            
              '
            
            )                  
            
              #
            
            
              字符串轉bytes
            
            
              
head_len 
            
            = len(bytes_head)                              
            
              #
            
            
              報頭的長度
            
            
pack_len = struct.pack(
            
              '
            
            
              i
            
            
              '
            
            
              ,head_len)

sk.send(pack_len)                                       
            
            
              #
            
            
              先發報頭的長度
            
            
sk.send(bytes_head)                                     
            
              #
            
            
              再發bytes類型的報頭
            
            
with open(r
            
              '
            
            
              dir\%s
            
            
              '
            
            %file_path,
            
              '
            
            
              rb
            
            
              '
            
            
              ) as f:
        
            
            
              while
            
            
               file_size:
                
            
            
              if
            
             file_size >=
            
               buffer:
                        content 
            
            = f.read(buffer)  
            
              #
            
            
               每次文件讀出的內容
            
            
                                      sk.send(content)
                        file_size 
            
            -=
            
               buffer
                
            
            
              else
            
            
              :
                        content 
            
            =
            
               f.read(file_size)
                        sk.send(content)
                        
            
            
              break
            
            
              
sk.close()
            
          

更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚洲国产成人久久综合碰 | 久久中文字幕一区二区三区 | 日产国产欧美视频一区精品 | 在线国产一区二区 | 日韩深夜福利 | 又大又粗进出白浆直流动态图 | 免费观看影院 | 久久国产精品一区 | 午夜色视频在线观看 | 欧美国产中文 | 国产成+人+亚洲+欧美+日韩 | 被摁着灌浓精囚禁高h1v1 | 激情视频免费在线观看 | 亚洲美女亚洲精品久久久久 | 国产精品第1页在线播放 | 亚洲第一av| 黄色网址在线免费播放 | 亚洲国产成人在线视频 | 亚洲欧美日本在线 | 欧美日韩国产手机在线观看视频 | 97精品国产高清久久久久蜜芽 | 国产精品成人国产乱一区 | 日韩欧美一区二区三区不卡 | 一区二区不卡在线观看 | 国产精品www视频免费看 | 91视频一区二区 | 日本一级在线 | 中文字幕日本视频 | 免费欧美黄色网址 | 91福利免费体验区观看区 | 狠狠综合久久综合鬼色 | 美女久久久久久久久久久 | 国产精品日韩 | 九九爱精品 | 成人免费影 | 亚洲国产伦理 | 日本护士xxxxx极品 | 嫩草影院免费 | 亚洲成人精品 | 亚洲欧美激情四射 | 特级毛片s级全部免费 |