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

Python语音通话App加入语音频道后崩溃 附双端代码求排查方案

语音通话应用加入频道崩溃、无法连接服务端排查

已定位的直接导致故障的代码问题

客户端侧问题

  • 音频发送逻辑错误:sendData 线程中直接将PyAudio的输入流对象当作音频数据通过socket发送,没有实际从流中读取采集到的音频帧,socket发送非字节类型数据会直接触发类型错误。
  • 音频接收逻辑完全写反:recive 线程没有从socket读取服务端转发的远端音频,反而持续读取本地麦克风采集的数据直接写到本地扬声器,完全没有走网络传输链路。
  • 全链路裸异常捕获静默吞错:两个工作线程的except块没有任何日志打印逻辑,所有运行时错误都被直接跳过,这就是崩溃时看不到任何报错信息的核心原因。
  • 资源回收逻辑缺失:异常触发后音频流、socket连接没有被统一回收,守护线程未配置,很容易触发资源泄漏导致进程无响应崩溃。

服务端侧问题

  • 异常处理变量作用域错误:handleVC 函数异常块中调用的conn是主监听循环的全局变量,不是当前触发断连的客户端连接fromConnection,多用户接入时这里会直接抛出未定义变量错误,失效连接无法被正确清理,还可能误关正常用户的连接。
  • Socket未配置基础参数:没有开启地址重用,服务端重启时容易出现端口占用导致绑定失败;没有配置超时机制,客户端异常断连后残留的无效连接会一直留在客户端列表,转发数据时持续触发断管错误。
  • 无异常日志:所有运行时错误被裸except吞掉,无法定位连接异常原因。

修复后可运行代码参考

服务端代码

import socket
import threading
import sys

def on_server_stop():
    log(consoleLog="Stopping Vc Server")
    sys.exit()


host = '0.0.0.0'
port = 5000

server = socket.socket()
# 开启地址重用,避免重启端口占用
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind((host, port)) 
server.listen()

log(consoleLog='Voice call server started and online!')

clientsInVC = []
# 加线程锁,避免多线程同时修改客户端列表出问题
list_lock = threading.Lock()

def handleVC(fromConnection):
    log(consoleLog="User connected to VC server.")
    while True:
        try:
            data = fromConnection.recv(4096)
            if not data:
                # 收到空数据代表连接断开
                raise ConnectionError("client disconnected")
            # 遍历转发时加锁,避免列表遍历过程中被其他线程修改
            with list_lock:
                for client in clientsInVC.copy():
                    if client != fromConnection:
                        try:
                            client.send(data)
                        except:
                            client.close()
                            clientsInVC.remove(client)
        except Exception as e:
            # 异常时清理当前连接
            with list_lock:
                if fromConnection in clientsInVC:
                    fromConnection.close()
                    clientsInVC.remove(fromConnection)
            log(consoleLog=f"User left VC server, reason: {str(e)}")
            break

while True:
    conn, addr = server.accept()
    with list_lock:
        clientsInVC.append(conn)
    thread = threading.Thread(target=handleVC, args=(conn,), daemon=True)
    thread.start()

客户端代码

import pyaudio
import socket
import threading

def JOINVC():
    print("started vc")
    vcclient = socket.socket()
    # 注意:如果服务端不在本机,这里要改成服务端实际IP,不要用127.0.0.1回环地址
    host = "127.0.0.1"
    port = 5000

    try:
        vcclient.connect((host, port))
    except Exception as e:
        print(f"连接语音服务失败: {str(e)}")
        return

    p = pyaudio.PyAudio()

    Format = pyaudio.paInt16
    Chunks = 4096  # 和服务端recv缓冲区大小对齐,减少音频卡顿
    Channels = 1
    Rate = 44100

    inputStream = p.open(format=Format, channels=Channels, rate=Rate, input=True, frames_per_buffer=Chunks)
    outputStream = p.open(format=Format, channels=Channels, rate=Rate, output=True, frames_per_buffer=Chunks)

    def sendData():
        while True:
            try:
                # 从麦克风读取音频帧再发送
                data = inputStream.read(Chunks, exception_on_overflow=False)
                vcclient.send(data)
            except Exception as e:
                print(f"发送线程异常: {str(e)}")
                break
        inputStream.close()

    def recive():
        while True:
            try:
                # 从socket读取远端音频再播放
                data = vcclient.recv(Chunks)
                if not data:
                    raise ConnectionError("server disconnected")
                outputStream.write(data, exception_on_underflow=False)
            except Exception as e:
                print(f"接收线程异常: {str(e)}")
                break
        outputStream.close()

    sendThread = threading.Thread(target=sendData, daemon=True)
    sendThread.start()
    reciveThread = threading.Thread(target=recive, daemon=True)
    reciveThread.start()

额外注意事项

  • 跨设备测试时先确认服务端5000端口的防火墙已经放开,客户端填写的服务端IP是局域网/公网可访问的实际IP。
  • 如果后续需要优化多人语音体验,可以给音频包增加序号、做抖动缓冲,避免音频卡顿、乱序。

内容的提问来源于stack exchange,提问作者No-Question123

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 23:24:26