You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于电脑A的指令实时控制电脑B启动/停止抓包进程?

解决方案

问题根源

你的代码无法实时处理消息主要有三个原因:

  1. ncat默认行为限制:ncat默认仅处理单次连接,只有当A的socket连接关闭后,才会把所有接收内容一次性输出,而非实时传递单条消息。
  2. stdout缓冲机制:subprocess的stdout存在缓冲,缓冲区未满或进程未结束时,readline()无法获取实时数据。
  3. 消息格式缺失换行:如果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,需要调整参数和读取逻辑:

  1. 给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  # 设置行缓冲
    )
    
  2. 确保A发送的每条消息末尾带有换行符,让readline()能实时读取单条指令。

额外注意事项

  • 原代码中elif message.startswith("Answer:")块存在未定义变量answer的错误,需替换为message。
  • 保存airodump-ng的进程对象,用terminate()终止比pkill更精准,避免误杀其他同名进程。

内容的提问来源于stack exchange,提问作者Emb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 00:27:13