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時不斷累加總數據和收到的數據長度