1、簡單的socket程序——傳輸簡短文字:shell
# -*- coding: utf-8 -*- # -*- Author: WangHW -*- import socket whw_client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) whw_client.connect(('127.0.0.1',9001)) while 1: cmd = input('>>>:').strip() if not cmd: continue whw_client.send(cmd.encode('utf-8')) recv_data = whw_client.recv(1024) data = recv_data.decode('utf-8') print('server data:',data)
# -*- coding: utf-8 -*- # -*- Author: WangHW -*- import socket whw_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) whw_server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) whw_server.bind(('127.0.0.1',9001)) whw_server.listen(5) print('listening......') conn,addr = whw_server.accept() #通訊循環 while 1: try: recv_data = conn.recv(1024) data = recv_data.decode('utf-8') print('client data:',data) conn.send(data.swapcase().encode('utf-8')) except ConnectionResetError: break conn.close()
演示以下:json
2、模擬SSH命令——解決粘包問題版:服務器
關於粘包問題的解決方案:socket
在服務器端,因爲解析出來的命令結果很是多,因此咱們在發送結果以前須要先給客戶端發送一個「報文」,這個報文保存着具體的命令結果的信息——其中關鍵的信息就是結果的長度,客戶端只有知道這個結果的長度後,才能制定相應的接收規則:ide
# -*- coding: utf-8 -*- # -*- Author: WangHW -*- import socket import json import struct whw_client = socket.socket(socket.AF_INET,socket.SOCK_STREAM) whw_client.connect(('127.0.0.1',9000)) while 1: try: cmd = input('>>>:').strip() if not cmd: continue #發命令 whw_client.send(cmd.encode('utf-8')) #1.收報頭長度 obj = whw_client.recv(10) #注意structunpack出來的[0]值爲長度信息 header_size = struct.unpack('i',obj)[0] #2.收報頭——根據報頭長度來收 header_bytes = whw_client.recv(header_size) #3.從報頭中解析出'total_size' header_json = header_bytes.decode('utf-8') header_dic = json.loads(header_json) total_size = header_dic['total_size'] #根據total_size開始接收真實的數據 recv_size = 0 recv_data = b'' while recv_size < total_size: res = whw_client.recv(1024) recv_data += res recv_size += len(res) print('命令結果:\n',recv_data.decode('gbk')) except Exception as e: whw_client.close()
# -*- coding: utf-8 -*- # -*- Author: WangHW -*- import socket import subprocess import json import struct whw_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) whw_server.bind(('127.0.0.1',9000)) whw_server.listen(5) print('Listening......') conn,addr = whw_server.accept() while 1: try: #收命令 cmd_recv = conn.recv(1024).decode('utf-8') #解析命令 obj = subprocess.Popen(cmd_recv,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) stdout = obj.stdout.read() stderr = obj.stderr.read() #將命令返回給客戶端 #1.製做固定報頭——注意報頭裏面要包含數據的總長度! header_dic = {'filename':'whw','total_size':len(stdout)+len(stderr)} header_json = json.dumps(header_dic) header_bytes = header_json.encode('utf-8') #2.發送報頭長度——struct:把數字打成固定長度 conn.send(struct.pack('i',len(header_bytes))) #3.發送報頭 conn.send(header_bytes) #4.發送真實數據 conn.send(stdout) conn.send(stderr) except ConnectionResetError: break conn.close()
演示以下:spa