通過socket執行dos命令
阿新 • • 發佈:2018-12-21
伺服器端程式碼
import socket, os server = socket.socket() server.bind(("localhost", 9999)) server.listen(5) while True: print("開始等待連線!!!") conn, addr = server.accept() print("客戶端地址:", addr[0], "埠:", addr[1]) print("客戶端連線成功\n") while True: try: print("開始工作".center(25, "-")) print("等待新指令:") msg = conn.recv(1024).decode() # 接收客戶端資訊並解碼,預設為UTF-8編碼 if not msg: continue elif msg == "bye" or msg == "exit": print("客戶端[%s:%s]已斷開連線!!!\n" % (addr[0], addr[1])) break else: print("執行新指令:%s" % msg) cmd_res = os.popen(msg).read() # 接受字串,相當於在dos命令介面,執行命令 cmd_size = len(cmd_res.encode("utf-8")) # 將命令的結果編譯成\xx\xx\xx,再進行統計字元數,因為結果中有漢字,編碼後的一個漢字為三個字元,所以客戶端接收的時候也要統計bytes型別的字元數 if cmd_size == 0: # 如果執行的是錯誤的命令,資料大小就為0,就執行下面的語句 conn.send("0".encode("utf-8")) # 傳送一個0給客戶端,客戶端接收的是個字串0就表示命令有誤,可以重新輸入 continue conn.send(str(cmd_size).encode("utf-8")) # 傳送響應資料的大小(全部是變為bytes型別後統計的字元數) cli_res = conn.recv(1024).decode() print(cli_res) conn.send(cmd_res.encode("utf-8")) # 傳送真實的資料 print("all send done。。。。。。\n") except ConnectionResetError as f: # 客戶端輕強制斷開時,服務端會報這個錯誤,利用斷言來捕獲異常 print(f) break
客戶端程式碼
import socket client = socket.socket() client.connect(("localhost", 9999)) while True: msg = input(">>>:").strip() if not msg: continue client.send(msg.encode("utf-8")) # 傳送命令 if msg == "bye" or msg == "exit": break cmd_size = client.recv(1024) # 接收響應資料的大小,此時接收的資料為bytes型別 if cmd_size.decode() == str(0): # 如果等於字串0就表示命令有誤 print("執行無結果,可能命令錯誤,請重新輸入") continue print("資料總大小為:", cmd_size.decode()) # 將結果解碼,如果不解碼,列印的結果中前面會多一個“b”例如:b"593" client.send("已收到發的資料。".encode("utf-8")) data_size = 0 # 資料的起始值 data_total = b"" # 空值,用於和後面接收的資料拼接起來,形成完整的響應資料 while data_size != int(cmd_size.decode()): # 判斷服務端傳送的大小和客戶端接收的大小是否一致,一致表示全部接收,不一致時一直迴圈接收資料 data = client.recv(1024) # 接收的是bytes型別 data_size += len(data) # 接收的資料大小,這裡的漢字也變成了bytes型別,一個漢字為3個字元,和服務端一致 data_total += data # 這裡不能解碼,因為拼接的型別就是bytes型別 else: print("實際接收的大小:", data_size) # 實際接收的總資料大小 print(data_total.decode()) # 將所有接收到的結果進行解碼,得到可見的結果 print("recv done ......") client.close()