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

Socket连接双向切换循环实现求助:现有代码阻塞问题排查

解决方案:基于Select的非阻塞双向通信

核心思路

用select.select()(Python)或select()(C)同时监听标准输入和Socket连接的可读事件,避免单线程下的阻塞问题,实现用户输入与Socket消息的双向切换处理。

BeagleBone Black 服务端代码(Python)

import socket
import select
import sys

def main():
    # 创建Socket并配置
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    # 绑定BBB的IP与端口(替换为你的BBB实际IP)
    server_address = ('0.0.0.0', 8888)
    server_socket.bind(server_address)
    server_socket.listen(1)
    print("等待电脑客户端连接...")
    
    # 接受客户端连接
    client_socket, client_addr = server_socket.accept()
    print(f"已连接:{client_addr}")

    # 监听列表:标准输入 + 客户端Socket
    inputs = [sys.stdin, client_socket]

    try:
        while True:
            # 等待可读事件触发
            readable, _, _ = select.select(inputs, [], [])
            for sock in readable:
                if sock == sys.stdin:
                    # 处理本地用户输入,发送给电脑客户端
                    user_input = sys.stdin.readline().strip()
                    if user_input.lower() == 'quit':
                        print("退出程序")
                        client_socket.sendall(user_input.encode('utf-8'))
                        break
                    client_socket.sendall(user_input.encode('utf-8'))
                elif sock == client_socket:
                    # 处理电脑端发来的消息
                    data = sock.recv(1024)
                    if not data:
                        print("客户端断开连接")
                        break
                    print(f"收到电脑消息:{data.decode('utf-8')}")
            else:
                continue
            break
    finally:
        client_socket.close()
        server_socket.close()

if __name__ == "__main__":
    main()

电脑客户端代码(Python)

import socket
import select
import sys

def main():
    # 连接BBB服务端(替换为你的BBB实际IP)
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    bbb_address = ('192.168.7.2', 8888)
    client_socket.connect(bbb_address)
    print("已连接到BeagleBone Black")

    # 监听列表:标准输入 + BBB Socket
    inputs = [sys.stdin, client_socket]

    try:
        while True:
            readable, _, _ = select.select(inputs, [], [])
            for sock in readable:
                if sock == sys.stdin:
                    # 处理本地用户输入,发送给BBB
                    user_input = sys.stdin.readline().strip()
                    if user_input.lower() == 'quit':
                        print("退出程序")
                        client_socket.sendall(user_input.encode('utf-8'))
                        break
                    client_socket.sendall(user_input.encode('utf-8'))
                elif sock == client_socket:
                    # 处理BBB发来的消息
                    data = sock.recv(1024)
                    if not data:
                        print("服务端断开连接")
                        break
                    print(f"收到BBB消息:{data.decode('utf-8')}")
            else:
                continue
            break
    finally:
        client_socket.close()

if __name__ == "__main__":
    main()

关键说明

  • select函数会阻塞直到监听的文件描述符中有可读事件,既不会卡在等待用户输入,也不会卡在等待Socket消息。
  • 当用户输入回车或Socket收到消息时,对应描述符会被标记为可读,进入对应处理分支。
  • 输入quit可触发双方退出并断开连接。

C语言版本核心逻辑(适用于BBB原生开发)

  1. 初始化fd_set集合,加入STDIN_FILENO和Socket文件描述符。
  2. 循环调用select(),判断哪个描述符可读。
  3. 分别处理标准输入读取(read(STDIN_FILENO, ...))和Socket接收(recv(...))。

排查要点

  • 确保BBB与电脑在同一局域网,IP地址配置正确。
  • 关闭双方防火墙或开放指定端口(如8888)。
  • 统一使用UTF-8编码处理文本,避免乱码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 10:45:38