直接幹實例1:python
需求: 使用TCP 顯示兩我的的1V1即時聊天服務編程
# 實現利用TCP協議的1V1聊天程序 from socket import * def V1(): # 建立對象 client_1 = socket(AF_INET, SOCK_STREAM) # 準備地址 address = ('192.168.2.104', 7877) # 發送地址 client_1.connect(address) while True: context = input('請留言:') if context == "exit": print('已結束聊天!') break try: client_1.send(context.encode('utf-8')) except: print('發送失敗!鏈接已中斷') break # 接收數據 server_data = client_1.recv(1024) while True: if server_data: print(f'來自回覆:{server_data.decode("utf-8")}') break else: break def main(): V1() if __name__ == '__main__': main()
# 實現利用TCP協議的1V1聊天程序 from socket import * def V2(): # 建立對象 client_2 = socket(AF_INET, SOCK_STREAM) # 準備地址 address = ('', 7877) # 發送地址 client_2.bind(address) client_2.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) # 最大鏈接數 client_2.listen(2) news_client, address_client = client_2.accept() while True: try: # 獲取內容 raw_data = news_client.recv(1024).decode('utf-8') except: print('鏈接已中斷!') break if raw_data.split(): print(f'來自: {address_client[0]} 留言:{raw_data}') context = input('回覆內容:') if context: news_client.send(context.encode('utf-8')) else: print('聊天已結束!') break else: print('聊天已結束!') break def main(): V2() if __name__ == '__main__': main()
結果: 效果初步實現,但不足的是隻能一句一句的回覆,同時間只能有一方說話 ( 例: 對講機 )服務器
實例二網絡
需求: 使用SOCKET實現文件的上傳,下載,查看功能socket
# 設定 L:讀 G: 下載 P: 上傳 from socket import * import pickle def upload(data): # 建立對象 upload_client = socket(AF_INET, SOCK_STREAM) # 超時管理 upload_client.settimeout(1) # 地址 upload_address = ('172.16.17.197', 7788) # 鏈接服務器 try: upload_client.connect(upload_address) except: print('鏈接服務端失敗!') # 打開文件 with open(f'{data[2:]}', 'rb') as f: # 讀取文件 file_data = f.read(1024) # 發送文件頭 upload_client.send((data + '|@_@|').encode('utf-8')) res = 0 while file_data: # 發送指令 res += upload_client.send(file_data) file_data = f.read(1024) upload_client.close() print(f'上傳{res} 個字節完成!') return True def download(data): # 建立對象 download_client = socket(AF_INET, SOCK_STREAM) # 超時管理 download_client.settimeout(1) # 地址 download_address = ('172.16.17.197', 7788) # 鏈接服務器 try: download_client.connect(download_address) # 發送指令 download_client.send(data.encode('utf-8')) except: print('鏈接服務端錯誤,發送失敗!') # 接收響應結果 raw_data = download_client.recv(1024) # 打開文件 with open(f'{data[2:]}_bak', 'wb') as f: # 寫入文件 while raw_data: f.write(raw_data) # print(raw_data) raw_data = download_client.recv(1024) f.close() download_client.close() print('下載完成!') return True def show(data): # 建立對象 show_client = socket(AF_INET, SOCK_STREAM) # 地址 show_address = ('172.16.17.197', 7788) # 超時管理 show_client.settimeout(1) # 鏈接服務器 try: show_client.connect(show_address) # 發送指令 show_client.send(data.encode('utf-8')) except: print('鏈接服務端錯誤,發送失敗!') # 接收響應結果 try: raw_data = show_client.recv(1024) except: print('服務端未響應') else: print('結果:', pickle.loads(raw_data)) show_client.close() def main(): while True: inputData = input('輸入命令:').strip() # 去除空格 if inputData[0].upper() == "L": show(inputData) elif inputData[0].upper() == "G": return_res = download(inputData) if return_res: # 下載完成 break else: print('下載失敗!') break elif inputData[0].upper() == "P": # 是否上傳完成 res = upload(inputData) if res: # 上傳完成 break else: print('上傳失敗!') break else: print('命令錯誤!') break if __name__ == '__main__': main()
import os from socket import * import pickle # 查看 def show(news_socket): # 查詢當前目錄下文件 files = os.listdir(os.getcwd()) # dumps 序列化 news_socket.send(pickle.dumps(files)) # 關閉 news_socket.close() # 下載 def download(news_socket, raw_data): # 獲取文件名 with open(f'{raw_data[2:]}', 'rb') as f: # 讀取文件 file_data = f.read(1024) send_size = 0 while file_data: # 發送字節碼 send_size += news_socket.send(file_data) file_data = f.read(1024) print(f'已下載:{send_size} 個字節') news_socket.close() def upload(file_data, news_socket): # 解出文件名 file_name = file_data.split(b'|@_@|')[0] file_name = file_name.split(b':')[1] with open(file_name.decode('utf-8') + '_bak', 'ab') as f: # 接收數據 files_data = file_data.split(b'|@_@|')[1] raw_data = news_socket.recv(1024) if files_data: f.write(files_data) while raw_data: # 寫入 f.write(raw_data) raw_data = news_socket.recv(1024) news_socket.close() def main(): # 建立對象 ftp_server = socket(AF_INET, SOCK_STREAM) # 綁定端口 ftp_server.bind(('', 7788)) # 同時最大鏈接數 ftp_server.listen(5) while True: try: # 建立新 news_socket, client_info = ftp_server.accept() # 獲取指令 # 獲取原始數據 指令 raw_data = news_socket.recv(1024) if raw_data[0:1].upper().decode('utf-8') == "L": # 查看 show(news_socket) elif raw_data[0:1].upper().decode('utf-8') == "G": # 下載 download(news_socket, raw_data.decode('utf-8')) elif raw_data[0:1].upper().decode('utf-8') == "P": upload(raw_data, news_socket) else: # 未檢測到內容輸入,退出操做 ftp_server.close() break except: print('參數異常!') break if __name__ == '__main__': main()
經過pickle的dumps方法把任何數據轉化成能夠網絡上傳輸的bytes類型,一般用於服務端序列化,客戶端反序列化code
import pickle var_a = {'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)} # 序列化 >>> var_b = pickle.dumps(var_a) >>> var_b b'\x80\x03}q\x00(X\x01\x00\x00\x00eq\x01K\nX\x01\x00\x00\x00aq\x02X\x03\x00\x00\x00strq\x03X\x01\x00\x00\x00fq\x04]q\x05(K\x01K\x02K\x03eX\x01\x00\x00\x00gq\x06K\x04K\x05K\x06\x87q\x07X\x01\x00\x00\x00bq\x08G@&333333X\x01\x00\x00\x00cq\t\x88X\x01\x00\x00\x00dq\nNu.' # 反序列化 >>> var_c = pickle.loads(var_b) >>> var_c {'e': 10, 'a': 'str', 'f': [1, 2, 3], 'g': (4, 5, 6), 'b': 11.1, 'c': True, 'd': None}
dump()用與保存序列化結果到文件,再稱之爲持久server
load()用於從文件中取內容後坍塌反序列化對象
持久化:一切內存裏的東西寫入硬盤後就持久化,開機後能再次看到ip
MSL是客戶端到服務端一次通訊的最長時間,若是在這個時間內沒有送達,認爲丟包了內存
一來一回最長時間就是2MSL,因此任何一方在發出信息後,若是2MSL內沒有收到回覆,就認爲丟包
一般在四次握手最後一次,客戶端發出最後確認分手包後,服務端在收到這個包後會斷開鏈接,沒法再發送消息
因此客戶端只有等待這麼長時間,若是在這個時間段內沒有再次收到新的分手包,就認爲服務端已經下線,我也是能夠離開