如何基于电脑A的指令实时控制电脑B启动/停止抓包进程?
解决方案
问题根源
你的代码无法实时处理消息主要有三个原因:
- ncat默认行为限制:ncat默认仅处理单次连接,只有当A的socket连接关闭后,才会把所有接收内容一次性输出,而非实时传递单条消息。
- stdout缓冲机制:subprocess的stdout存在缓冲,缓冲区未满或进程未结束时,
readline()无法获取实时数据。 - 消息格式缺失换行:如果A发送的消息末尾没有换行符,
readline()会一直阻塞等待换行,直到连接断开才返回全部内容。
推荐方案:直接用Python Socket监听(替代ncat)
去掉ncat中间层,直接在B上用Python的socket模块监听端口,能完全控制消息的实时接收和处理,避免缓冲和连接模式的问题。
修改后的B端代码
import socket import subprocess airodump_process = None def handle_client_connection(conn): global airodump_process while True: # 按字节读取消息,可根据实际调整最大接收长度 data = conn.recv(1024) if not data: break # 客户端断开连接 message = data.decode().strip() print("Received message:", message) # 处理指令 if message == "START_CAPTURE": print("Starting capture...") # 保存进程对象,避免后续pkill误杀其他同名进程 airodump_process = subprocess.Popen([ "airodump-ng", "--channel", "<my_channel>", "--bssid", "<my_bssid>", "--write", "capture", "<interface>" ]) elif message == "STOP_CAPTURE": print("Stopping capture...") if airodump_process and airodump_process.poll() is None: airodump_process.terminate() airodump_process.wait() else: # 兜底处理,避免进程未被正确保存的情况 subprocess.run(["pkill", "airodump-ng"], check=False) elif message.startswith("Answer:"): # 修正原代码错误:使用message而非未定义的answer变量 with open("answer.txt", "a") as file: file.write(message + "\n") # 加换行避免内容堆叠 elif message == "STOP_SCRIPT": print("Stopping script...") # 先终止抓包进程(如果存在) if airodump_process and airodump_process.poll() is None: airodump_process.terminate() airodump_process.wait() conn.close() return def start_server(): HOST = "<B的IP地址>" # 例如192.168.1.100 PORT = <端口号> # 例如12345 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.bind((HOST, PORT)) s.listen() print(f"Listening on {HOST}:{PORT}...") while True: conn, addr = s.accept() with conn: print(f"Connected by {addr}") handle_client_connection(conn) if __name__ == '__main__': start_server()
配套A端代码调整
确保A发送的每条指令格式清晰(末尾可加换行符,不影响处理):
import socket HOST = "<B的IP地址>" PORT = <端口号> with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.connect((HOST, PORT)) # 发送启动抓包指令 s.sendall(b"START_CAPTURE") # 执行你的数据获取逻辑... # 发送停止抓包指令 s.sendall(b"STOP_CAPTURE") # 发送观测数据 s.sendall(b"Answer: 观测内容示例") # 停止B端脚本 s.sendall(b"STOP_SCRIPT")
备选方案:改进ncat使用方式
如果坚持用ncat,需要调整参数和读取逻辑:
- 给ncat添加
-k参数保持监听(接受多连接),--no-buffer禁用缓冲:ncat_process = subprocess.Popen( ["ncat", "-l", "<ip_address>", "-p", "<port>", "-k", "--no-buffer"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, bufsize=1 # 设置行缓冲 ) - 确保A发送的每条消息末尾带有换行符,让
readline()能实时读取单条指令。
额外注意事项
- 原代码中
elif message.startswith("Answer:")块存在未定义变量answer的错误,需替换为message。 - 保存
airodump-ng的进程对象,用terminate()终止比pkill更精准,避免误杀其他同名进程。
内容的提问来源于stack exchange,提问作者Emb
相关产品推荐
相关产品推荐

