我的申请有问题 . 我尝试使用asyncio库中的客户端和服务器UDP同时实现发送和接收声音 . 我的客户端在连接后只发送一个数据块 . 发送此数据后,客户端停止传输 .

客户:

enter image description here

服务器获取数据并重新发送给发件人(只是echo服务器)

enter image description here

我的目标是 Build 两个独立的通信循环:发送和接收 .

客户代码:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat May 26 21:22:22 2018

@author: afar
"""
import os
import sys
import pyaudio
import socket
import asyncio
from threading import Thread

"""
class MyUDPServer(asyncio.DatagramProtocol):
...
    def connection_made(self, transport):
        self.transport = transport

        # Allow receiving multicast broadcasts
        sock = self.transport.get_extra_info('socket')
        group = socket.inet_aton('239.255.255.250')
        mreq = struct.pack('4sL', group, socket.INADDR_ANY)
        sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
"""

class MyVOIPProtocol(asyncio.DatagramProtocol):
    FORMAT = pyaudio.paInt16
    CHUNK = 512
    WIDTH = 1
    CHANNELS = 1
    RATE = 16000
    FACTOR = 1

    def __init__(self, loop):

        self.loop = loop
        self.transport = None

        self.host = '127.0.0.1'
        self.port = 9999
        self.size = 2048

        self.p = pyaudio.PyAudio()

        self.stream = self.p.open(format=self.FORMAT,
                                  channels=self.CHANNELS,
                                  rate=self.RATE,
                                  input=True,
                                  output=True,
                                  frames_per_buffer=self.CHUNK)


        super().__init__()

    def send_voice(self):
        self.voice_msg =  self.stream.read(self.CHUNK)
        print("record chunk")
        self.transport.sendto(self.voice_msg)

    def connection_made(self, transport):
        self.transport = transport
        self.send_voice()

    def datagram_received(self, data, addr):
        print("Recived from: ", addr)
        self.stream.write(data)
        print("stream write done")

    def error_received(self, exc):
        print('Error received:', exc)


    def stop_call(self):        
        self.stream.stop_stream()
        self.stream.close()


loop = asyncio.get_event_loop()
#loop.create_task(MyVOIPProtocol(loop).foo())
connect = loop.create_datagram_endpoint(
        lambda: MyVOIPProtocol(loop),
        remote_addr=('127.0.0.1', 9999))

loop.run_until_complete(connect)
loop.run_forever()

#transport.close()
#loop.close()

服务器代码:

import asyncio
import sys


class EchoServerProtocol(asyncio.DatagramProtocol):

    def connection_made(self, transport):
        self.transport = transport

    def datagram_received(self, voice_msg, addr):
        print('Received voic - size: %d bytes from: %s' % (sys.getsizeof(voice_msg), addr))
        self.transport.sendto(voice_msg, addr)

loop = asyncio.get_event_loop()
print("Starting UDP server")
# One protocol instance will be created to serve all client requests
listen = loop.create_datagram_endpoint(
    EchoServerProtocol, local_addr=('127.0.0.1', 9999))
transport, protocol = loop.run_until_complete(listen)

try:
    loop.run_forever()
except KeyboardInterrupt:
    pass

transport.close()
loop.close()