PYTHON-TCP 粘包

1.TCP的模板代碼    收發消息的循環  通信循環    不斷的鏈接客戶端循環  鏈接循環    判斷 用於判斷客戶端異常退出(拋異常)或close(死循環)    半鏈接池backlog   listen(5)        佔用的是內存空間  listen監聽請求限制的是請求數 不是連接數        什麼狀況下會進入半鏈接池:來不及處理accept  或者客戶端單方面終止鏈接    半鏈接池的工做原理        目前咱們的程序是單線程 服務器要麼處理通信要麼處理鏈接請求 沒法同時進行        1 必須綁定規定的ip和port        2 必須對外穩定提供服務        3 必須能支持併發    服務端須要遵循的原則:        1. 服務端與客戶端都須要有惟一的地址,可是服務端的地址必須固定/綁定        2. 對外一直提供服務,穩定運行        3. 服務端應該支持併發2.遠程CMD    粘包問題    一方發送空數據 致使程序卡死  從此會經過多線程處理3.粘包問題 TCP:流式協議    引發粘包的TCP特色:        1 數據流沒有開頭也沒有結果,像水流同樣        2 TCP協議有一個nagle算法,解決粘包的方案  自定義報頭    1.先用報頭傳輸數據的長度        對於咱們遠程CMD程序來講 只要先傳輸長度就能解決粘包的問題        可是若是作得是一個文件上傳下載  除了數據的長度 還須要傳輸文件的名字 md5等等信息        又該如何?    解決方法:        發送方            1.先告訴對方你要發的數據的長度            2.在發送真實數據        接收方            1.先接收數據的長度信息            2.根據長度信息循環獲取直到以獲取的長度等於總長度    2.自定義複雜報頭  完成發送一些額外的信息 例如文件名        1.將要發送的額外數據打包成一個字典做爲報頭        3.先發送報頭的bytes長度(轉json字符串 轉bytes字節)        4.再發送報頭數據        5.最後發送真實數據    #服務端:                           #客戶端:        # 執行命令        # 顯示錯誤信息和正確信息        # 製做一個報頭信息 (轉json字符串 轉bytes字節)        # 發送報頭長度                  # 先接收報頭的長度(int)        # 發送報頭                      # 接收報頭(字節)        # 發送真實數據                  # 解析報頭 轉爲json字符串str,再轉爲字典dic                                        # 根據報頭內的信息,收取真實的數據    涉及模塊:    struct        整型轉字節,轉成的bytes是固定長度的            i 表示int 長度爲4字節   q表示long int 長度爲8字節            print(len(struct.pack("i",10240)))        字節轉整型 獲得一個元祖!!!            print(struct.unpack("q",struct.pack("q",10240))[0])        struct.pack('i',整形變量)        struct.unpack('i',字節變量)    服務器端示例:             # 爲了方便存取 能夠把須要的信息打包爲一個字典            dic{                "filename":"倉老師視頻教學 如何作炸雞!",                "md5":"xzxbzxkbsa1212121",                "total_size":2121221            }            # 字典轉字符串? json            head_dic =  str(dict)            bytes = head_dic.encode("utf-8")            # 先發送這個字典字符串的長度            dic_len = len(head_dic)            #將長度轉爲了 字節            bytes_len = struct.pack("i",dic_len)            # 發送報頭的長度            c.send(bytes_len)            # 發送真實數據            c.send(xxx.mp4.bytes)            TCP能傳的只有字節# 服務端#執行結果長p_len=len(stdout)+len(stderr)# 將報頭信息dic轉json字符串,編碼爲字節,字節的長度,用struct固定,發送報頭長度# 發送報頭(編碼爲字節)# 再發送真實數據stdout ,stderr# 客戶端# 先接收報頭長度 用struct unpack拿到元祖取[0]# 接收報頭# 解析報頭,解碼,json反序列化拿到字典,經過字典獲取字典中的總長度# 根據報頭信息,收取真實的數據 按1024接受,判斷當總長度>0時不斷累加總數據和收到的數據長度
相關文章
相關標籤/搜索