c# - 从 TCP Socket 接收和发送连续数据

标签 c# networking audio tcp handler

我已经快疯了。所以我决定寻求帮助。

场景:在网页中,通过 TCP 套接字连接到服务器,并在循环中逐字节获取数据。这些数据是连续的。

问题:如何制作一个 WebSocket 来接收和发送数据给播放器( html5 标签)。

Default.aspx

<asp:Literal ID="ltrPlayer" runat="server" />

Default.aspx.cs

protected void Page_Load(object sender, EventArgs e)
{
    string tele = HttpContext.Current.Request.QueryString["tele"];
    string ramal = HttpContext.Current.Request.QueryString["ramal"];
    string dac = HttpContext.Current.Request.QueryString["dac"];
    string cti = HttpContext.Current.Request.QueryString["cti"];

    if ((tele != null) && (ramal != null) && (dac != null) && (cti != null))
    {
        string strAudio = "<audio controls='controls'>";
        strAudio += "<source src='Play.ashx?tele=" + tele + "&ramal=" + ramal + "&dac=" + dac + "&cti=" + cti + "' type='audio/x-wav' controls preload='auto'>";
        strAudio += "Seu browser não oferece suporte a este player.";
        strAudio += "</audio>";

        ltrPlayer.Text = strAudio;
    }
}

播放.ashx

<%@ WebHandler Language="C#" Class="Play" %>

using System;
using System.Web;

using System.Net;
using System.IO;
using Alvas.Audio; // Make the conversion VOX to WAV
using System.Media;
using System.Configuration;

using System.Net.Sockets;
using System.Text;


public class Play : IHttpHandler
{
    private NetworkStream ns;

    public void ProcessRequest(HttpContext context)
    {
        string tele = HttpContext.Current.Request.QueryString["tele"];
        string ramal = HttpContext.Current.Request.QueryString["ramal"];
        string dac = HttpContext.Current.Request.QueryString["dac"];
        string cti = HttpContext.Current.Request.QueryString["cti"];   

        if ((tele != null) && (ramal != null) && (dac != null) && (cti != null))
        {
            try
            {
                TcpClient oClient = new TcpClient();

                oClient.Connect(tele, 22000);

                ns = oClient.GetStream();
                write(ns, "ondelogar");

                ns = oClient.GetStream();
                write(ns, "monitorarRamalViaRede(tele;ramal;dac;cti)");

                Thread.Sleep(1000);                

                do
                {
                    if (oClient.GetStream().DataAvailable == true)
                    {
                        using (StringReader reader = new StringReader(read(ns)))
                        {
                            string line;

                            while ((line = reader.ReadLine()) != null)
                            {
                                Byte[] byteOut = new Byte[line.Length / 2];

                                int i = 0;
                                while (i < (line.Length / 2))
                                {
                                    byteOut[i / 2] = Convert.ToByte(line.Substring(i, 2), 16);
                                    i = i + 2;
                                }

                                Stream s = new MemoryStream(byteOut);
                                BinaryReader br = new BinaryReader(s);
                                MemoryStream pcmStream = new MemoryStream();
                                IntPtr pcmFormat = AudioCompressionManager.GetPcmFormat(1, 16, 6000);
                                WaveWriter ww = new WaveWriter(pcmStream, AudioCompressionManager.FormatBytes(pcmFormat));
                                Vox.Vox2Wav(br, ww);
                                WaveReader wr = new WaveReader(pcmStream);

                                byte[] pcmData = pcmStream.ToArray();

                                br.Close();
                                ww.Close();
                                wr.Close();
                                pcmStream.Close();
                                Array.Clear(byteOut, 0, byteOut.Length);

                                HttpContext.Current.Response.Clear();
                                HttpContext.Current.Response.AddHeader("content-disposition", string.Format("attachment; filename=\"{0}\"", "BufferDeAudio"));
                                HttpContext.Current.Response.ContentType = "audio/x-wav";
                                HttpContext.Current.Response.BinaryWrite(pcmData);
                                HttpContext.Current.Response.End();             
                            }
                        }
                    }
                }
                while (oClient.GetStream().DataAvailable == true);

                ns.Close();
            }
            catch (Exception)
            {

            }

            HttpContext.Current.Response.End();
        }
    }

    private void write(NetworkStream ns, string message)
    {
        byte[] msg = Encoding.ASCII.GetBytes(message + Environment.NewLine);
        ns.Write(msg, 0, msg.Length);
    }

    private string read(NetworkStream ns)
    {
        StringBuilder sb = new StringBuilder();

        if (ns.CanRead)
        {
            byte[] readBuffer = new byte[1024];

            int numBytesRead = 0;

            do
            {
                numBytesRead = ns.Read(readBuffer, 0, readBuffer.Length);
                sb.AppendFormat("{0}", Encoding.ASCII.GetString(readBuffer, 0, numBytesRead));
                sb.Replace(Convert.ToChar(24), ' ');
                sb.Replace(Convert.ToChar(255), ' ');
                sb.Replace('?', ' ');
            }

            while (ns.DataAvailable);
        }

        return sb.ToString();
        }                                        

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

然后,当循环逐行接收数据时,我将发送给播放器。但我听到的唯一声音是循环的最后一行。

我试图将播放器放入线程中,但没有成功。

这可能吗?有什么想法吗?

最佳答案

您关闭 while 循环内的响应流。这将关闭连接并中断传出流。

考虑这样的事情:

HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader(...))
HttpContext.Current.Response.ContentType = "audio/x-wav";

...

while ((line = reader.ReadLine()) != null)
{
    ...

    HttpContext.Current.Response.BinaryWrite(pcmData);
    HttpContext.Current.Response.Flush();
}
HttpContext.Current.Response.End();            

关于c# - 从 TCP Socket 接收和发送连续数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13311564/

相关文章:

c# - 入口点在没有构建 IHost 的情况下退出

c# - Umbraco:在用户控件中列出子节点

C:使用选择调用,当我阅读时,我如何跟踪数据?

linux - 在 Linux 机器上运行 whois -h 时识别 IP 地址

linux - 如何配置 docker default bridge 使用异常网络配置?

c++ - 树莓派SFML播放音频

python - 如何保存文件夹和子文件夹中的音频文件(.wav)的频谱图?

c# - 我应该执行每个查询还是单个查询?

c# - INotifyPropertyChanged 未触发 PropertyChanged

audio - 如何从音频剪辑中删除漂移的直流偏移?