c# 语言通信

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using System.Collections;
using System.Threading;
using System.Net;
using System.Net.Sockets;

namespace MatureVoice
{
    public partial class Voice : DevComponents.DotNetBar.Office2007Form
    {
        public Voice()
        {
            InitializeComponent();
        }

        private Point posMouse;
        private NetChat netchat1;

        private void Voice_Load(object sender, EventArgs e)
        {
            netchat1 = new NetChat(8000);
            this.Text = "本机:" + netchat1.BindSelf(netchat1.LocalIPEnd);
          //  this.comboIP.Text = Dns.GetHostAddresses(Dns.GetHostName())[0].ToString();
          //  MessageBox.Show(Dns.GetHostAddresses(Dns.GetHostName())[0].ToString());
        }

        private void Voice_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                posMouse.X = e.X;
                posMouse.Y = e.Y;
            }
        }

        private void Voice_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                Voice.ActiveForm.Top = Control.MousePosition.Y - posMouse.Y - SystemInformation.FrameBorderSize.Height - SystemInformation.CaptionHeight;
                Voice.ActiveForm.Left = Control.MousePosition.X - posMouse.X - SystemInformation.FrameBorderSize.Width;

            }
        }
      
        private void btnSelect_Click(object sender, EventArgs e)
        {
        

        }

        //建立一个委托
        private delegate void FormHandel(string strArgu);

        private void FormWrite(string strText)
        {
            if (InvokeRequired)
            {
                FormHandel handel1 = new FormHandel(FormWrite);
                this.Invoke(handel1, new object[] { strText });
            }
            else
            {
                lblStatus.Text = strText;
            }
        }

        private void Voice_FormClosing(object sender, FormClosingEventArgs e)
        {

        }

        private void lblStatus_TextChanged(object sender, EventArgs e)
        {
            timer1.Start();
        }
        private int intTickedTimes = 0;
        private void timer1_Tick(object sender, EventArgs e)
        {
            intTickedTimes++;
            if (intTickedTimes > 6)
            {
                timer1.Stop();
                intTickedTimes = 0;
            }
            else
            {
                lblStatus.ForeColor = intTickedTimes % 2 == 0 ? Color.MidnightBlue : Color.Red;
            }
        }
        string ip = "";
        private void btnSubmit_Click(object sender, EventArgs e)
        {
          
        }

        private void btnChat_Click(object sender, EventArgs e)
        {//先初始化语音模块,启动监听方法,再启动语音采集方法
            progressBar1.Maximum = 60;
            try
            {
                netchat1.SetRemoteIPEnd(ip, 8000);
                FormWrite("已经接通……!");
            }
            catch
            {
                FormWrite("非法的IP地址");
                btnChat.Enabled = false;
            }
            if (btnChat.Text == "接听")
            {
                btnChat.Text = "持断";
                i = 0;
                timer2.Enabled = true;
                 try
                {
                    netchat1.Intptr = this.Handle;
                    netchat1.InitVoice();
                }
                catch
                {
                    FormWrite("声音模块初始化失败");
                }
                try
                {
                    netchat1.Listen();
                }
                catch
                {
                    FormWrite("监听模块异常");
                }
                try
                {
                    netchat1.StartSendVoice();
                }
                catch
                {
                    if (MessageBox.Show("应用程序出现问题,需要重新启动应该程序嘛?", "系统提示", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) == DialogResult.Yes)
                    {
                        Application.Exit();//先关闭应用程序
                        System.Diagnostics.Process.Start(System.Reflection.Assembly.GetExecutingAssembly().Location);
                    }

                }
            }
            else
            {
                netchat1.Stop();
                btnChat.Text = "接听";
                timer1.Enabled = false;
                timer2.Enabled = false;
            }
        }
        int i = 0;
        private void timer2_Tick(object sender, EventArgs e)
        {
            i++;
            lblStatus.Text = i.ToString();
            progressBar1.Value = i;
            if (i==60)
            {
                i = 0;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            ip = "192.168.50.5";
        }

        private void button3_Click(object sender, EventArgs e)
        {
            ip = "192.168.50.31";
        }

        private void button4_Click(object sender, EventArgs e)
        {
            ip = "192.168.50.36";
        }

        private void button5_Click(object sender, EventArgs e)
        {
            ip = "192.168.50.33";
        }
    }
}

 

 

 

using System;
using System.Collections.Generic;
using System.Text;

using System.Net;
using System.Diagnostics;
using System.Collections;
using System.DirectoryServices;
using System.Threading;
namespace MatureVoice
{
    class ListUsers
    {
        public static ArrayList GetComputerList()
        {
            ArrayList list = new ArrayList();
            DirectoryEntry root = new DirectoryEntry("WinNT:");
            DirectoryEntries domains = root.Children;
            domains.SchemaFilter.Add("domain");
            foreach (DirectoryEntry domain in domains)
            {
                DirectoryEntries computers = domain.Children;
                computers.SchemaFilter.Add("computer");
                foreach (DirectoryEntry computer in computers)
                {
                    object[] arr = new string[3];
                    IPHostEntry iphe = null;
                    try
                    {
                        iphe = Dns.GetHostByName(computer.Name);
                    }
                    catch
                    {
                        continue;
                    }
                    arr[0] = domain.Name;
                    arr[1] = computer.Name;
                    if (iphe != null && iphe.AddressList.Length > 0)
                    {
                        arr[2] += iphe.AddressList[0].ToString();
                    }
                    else
                        arr[2] = "";
                    list.Add(arr);
                }
            }
            return list;
        }
      
    }
}

using System;
using System.Collections.Generic;
using System.Text;

using System.Threading;
using System.Net;
using System.Net.Sockets;


namespace MatureVoice
{
    class NetChat
    {
        private int intPointVariable = 1;//端口增长幅度
        private IPEndPoint ipeLocal;
        private Socket LocalSocket;
        private IPEndPoint ipeRemote;
        private int intMaxDataSize = 10000;//接收缓冲区长度
        private VoiceCapture voicecapture1 = new VoiceCapture();
        private IntPtr intptr;

        public IntPtr Intptr
        {
            set
            {
                intptr = value;
            }
        }

        public IPEndPoint LocalIPEnd
        {
            get { return ipeLocal; }
        }

        public NetChat(int intPort)
        {
            ipeLocal = new IPEndPoint(IPAddress.Any, intPort);//配置本地IP 和 端口
            LocalSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        }

        public NetChat(string strIP, int intPort)
        {
            ipeLocal = new IPEndPoint(IPAddress.Parse(strIP), intPort);//配置本地IP 和 端口
            LocalSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        }

        /// <summary>
        /// 绑定自己的IP和端口
        /// </summary>
        /// <param name="ipe">IP端口对</param>
        /// <returns>绑定成功返回true</returns>
        public string  BindSelf(IPEndPoint ipe)
        {
            while (true)
            {
                try
                {
                    LocalSocket.Bind((EndPoint)ipeLocal);
                    return ipeLocal.Address.ToString()+" : "+ipeLocal.Port;
                }
                catch
                {
                    ipeLocal.Port = 8000 + intPointVariable;
                    intPointVariable++;
                }
            }

        }

        /// <summary>
        /// 设置远程IP端口节点
        /// </summary>
        /// <param name="strRemote">远程IP</param>
        /// <param name="intPort">远程端口</param>
        public void SetRemoteIPEnd(string strRemote, int intPort)
        {
            ipeRemote = new IPEndPoint(IPAddress.Parse(strRemote), intPort);
        }

        private Thread ListenThread;
        private byte[] bytData;

        /// <summary>
        /// 监听方法,用于监听远程发送到本机的信息
        /// </summary>
        public void Listen()
        {
            ListenThread = new Thread(new ThreadStart(DoListen));
            ListenThread.IsBackground = true;//设置为后台线程,这样当主线程结束后,该线程自动结束
            ListenThread.Start();
        }

        private EndPoint epRemote;

        /// <summary>
        /// 监听线程
        /// </summary>
        private void DoListen()
        {
            bytData = new byte[intMaxDataSize];
            epRemote = (EndPoint)(new IPEndPoint(IPAddress.Any, 0));

            //可能会抛出一个异常
            while (true)
            {
                if (LocalSocket.Poll(5000, SelectMode.SelectRead))
                {//每5ms查询一下网络,如果有可读数据就接收
                    LocalSocket.BeginReceiveFrom(bytData, 0, bytData.Length, SocketFlags.None, ref epRemote, new AsyncCallback(ReceiveData), null);
                }
            }
        }

        /// <summary>
        /// 接收数据
        /// </summary>
        /// <param name="iar"></param>
        private void ReceiveData(IAsyncResult iar)
        {
            int intRecv = 0;
            try
            {
                intRecv = LocalSocket.EndReceiveFrom(iar, ref epRemote);
            }
            catch
            {
                throw new Exception();
            }
            if (intRecv > 0)
            {
                byte[] bytReceivedData = new byte[intRecv];
                Buffer.BlockCopy(bytData, 0, bytReceivedData, 0, intRecv);
                voicecapture1.GetVoiceData(intRecv, bytReceivedData);//调用声音模块中的GetVoiceData来从字节数组中获取声音并播放
            }
        }

        public void InitVoice()
        {
            voicecapture1 = new VoiceCapture();
            voicecapture1.NotifyNum = 10;
            voicecapture1.NotifySize = 4410;
            voicecapture1.LocalSocket = LocalSocket;
            voicecapture1.RemoteEndPoint = (EndPoint)ipeRemote;
            voicecapture1.Intptr = intptr;
            voicecapture1.InitVoice();
        }

        public void StartSendVoice()
        {
            voicecapture1.StartVoiceCapture();
        }

        public void Stop()
        {
            if (ListenThread != null && ListenThread.IsAlive == true)
            {
                ListenThread.Abort();
            }
            voicecapture1.Stop();
        }
    }
}

 

 


using System;
using System.Collections.Generic;
using System.Text;

using System.IO;
using System.Threading;
using Microsoft.DirectX;
using Microsoft.DirectX.DirectSound;
using System.Net.Sockets;
using System.Net;

namespace MatureVoice
{
    class VoiceCapture
    {
        private MemoryStream memstream;//内存流
        private SecondaryBuffer secBuffer;//辅助缓冲区
        private int iNotifySize = 0;//通知大小
        private int iBufferSize = 0;//捕捉缓冲区大小
        private CaptureBuffer capturebuffer;//捕捉缓冲区对象
        private AutoResetEvent notifyEvent;//通知事件
        private Thread notifyThread;//通知线程
        private int iNotifyNum=0;//通知个数
        private Notify myNotify;//通知对象
        private Capture capture;//捕捉设备对象
        private Device PlayDev;//播放设备对象
        private BufferDescription buffDiscript;
        private Socket Client;
        private EndPoint epServer;
        private int iBufferOffset=0;//捕捉缓冲区位移
        private IntPtr intptr;//窗口句柄

        public IntPtr Intptr
        {
            set
            {
                intptr = value;
            }
        }

        public int NotifySize
        {
            set
            {
                iNotifySize = value;
            }

        }

        public int NotifyNum
        {
            set
            {
                iNotifyNum = value;
            }
        }

        public Socket LocalSocket
        {
            set
            {
                Client = value;
            }
        }

        public EndPoint RemoteEndPoint
        {
            set
            {
                epServer = value;
            }
        }


        /// <summary>
        /// 初始化相关操作
        /// </summary>
        public void InitVoice()
        {//初始化声音相关设置:(1)捕捉缓冲区(2)播放缓冲区
            if (!CreateCaputerDevice())
            {
                throw new Exception();
            }//建立设备对象
            CreateCaptureBuffer();//建立缓冲区对象
            CreateNotification();//设置通知及事件
            //======(2)==============
            if (!CreatePlayDevice())
            {
                throw new Exception();
            }
            CreateSecondaryBuffer();
        }

        /// <summary>
        /// 启动声音采集
        /// </summary>
        public void StartVoiceCapture()
        {
            capturebuffer.Start(true);//true表示设置缓冲区为循环方式,开始捕捉
        }

        /// <summary>
        /// 创建用于播放的音频设备对象
        /// </summary>
        /// <returns>创建成功返回true</returns>
        private bool CreatePlayDevice()
        {
            DevicesCollection dc = new DevicesCollection();
            Guid g;
            if (dc.Count > 0)
            {
                g = dc[0].DriverGuid;
            }
            else
            { return false; }
            PlayDev = new Device(g);
            PlayDev.SetCooperativeLevel(intptr, CooperativeLevel.Normal);
            return true;
        }

        /// <summary>
        /// 创建辅助缓冲区
        /// </summary>
        private void CreateSecondaryBuffer()
        {
            buffDiscript = new BufferDescription();
            WaveFormat mWavFormat = SetWaveFormat();
            buffDiscript.Format = mWavFormat;
            iNotifySize = mWavFormat.AverageBytesPerSecond / iNotifyNum;//设置通知大小
            iBufferSize = iNotifyNum * iNotifySize;
            buffDiscript.BufferBytes = iBufferSize;
            buffDiscript.ControlPan = true;
            buffDiscript.ControlFrequency = true;
            buffDiscript.ControlVolume = true;
            buffDiscript.GlobalFocus = true;
            secBuffer = new SecondaryBuffer(buffDiscript, PlayDev);
            byte[] bytMemory = new byte[100000];
            memstream = new MemoryStream(bytMemory, 0, 100000, true, true);
            //g729 = new G729();
            //g729.InitalizeEncode();
            //g729.InitalizeDecode();
        }

        /// <summary>
        /// 创建捕捉设备对象
        /// </summary>
        /// <returns>如果创建成功返回true</returns>
        private bool CreateCaputerDevice()
        {
            //首先要玫举可用的捕捉设备
            CaptureDevicesCollection capturedev = new CaptureDevicesCollection();
            Guid devguid;
            if (capturedev.Count > 0)
            {
                devguid = capturedev[0].DriverGuid;
            }
            else
            {
                System.Windows.Forms.MessageBox.Show("当前没有可用于音频捕捉的设备", "系统提示");
                return false;
            }
            //利用设备GUID来建立一个捕捉设备对象
            capture = new Capture(devguid);
            return true;
        }

        /// <summary>
        /// 创建捕捉缓冲区对象
        /// </summary>
        private void CreateCaptureBuffer()
        {
            //想要创建一个捕捉缓冲区必须要两个参数:缓冲区信息(描述这个缓冲区中的格式等),缓冲设备。
            WaveFormat mWavFormat = SetWaveFormat();
            CaptureBufferDescription bufferdescription = new CaptureBufferDescription();
            bufferdescription.Format = mWavFormat;//设置缓冲区要捕捉的数据格式
            iNotifySize = mWavFormat.AverageBytesPerSecond / iNotifyNum;//1秒的数据量/设置的通知数得到的每个通知大小小于0.2s的数据量,话音延迟小于200ms为优质话音
            iBufferSize = iNotifyNum * iNotifySize;
            bufferdescription.BufferBytes = iBufferSize;
            bufferdescription.ControlEffects = true;
            bufferdescription.WaveMapped = true;
            capturebuffer = new CaptureBuffer(bufferdescription, capture);//建立设备缓冲区对象

        }

        //设置通知
        private void CreateNotification()
        {
            BufferPositionNotify[] bpn = new BufferPositionNotify[iNotifyNum];//设置缓冲区通知个数
            //设置通知事件
            notifyEvent = new AutoResetEvent(false);
            notifyThread = new Thread(RecoData);//通知触发事件
            notifyThread.IsBackground = true;
            notifyThread.Start();
            for (int i = 0; i < iNotifyNum; i++)
            {
                bpn[i].Offset = iNotifySize + i * iNotifySize - 1;//设置具体每个的位置
                bpn[i].EventNotifyHandle = notifyEvent.Handle;
            }
            myNotify = new Notify(capturebuffer);
            myNotify.SetNotificationPositions(bpn);

        }

        //线程中的事件
        private void RecoData()
        {
            while (true)
            {
                // 等待缓冲区的通知消息
                notifyEvent.WaitOne(Timeout.Infinite, true);
                // 录制数据
                RecordCapturedData(Client,epServer);
            }
        }

        //真正转移数据的事件,其实就是把数据传送到网络上去。
        private void RecordCapturedData(Socket Client,EndPoint epServer )
        {
            byte[] capturedata = null;
            int readpos = 0, capturepos = 0, locksize = 0;
            capturebuffer.GetCurrentPosition(out capturepos, out readpos);
            locksize = readpos - iBufferOffset;//这个大小就是我们可以安全读取的大小
            if (locksize == 0)
            {
                return;
            }
            if (locksize < 0)
            {//因为我们是循环的使用缓冲区,所以有一种情况下为负:当文以载读指针回到第一个通知点,而Ibuffeoffset还在最后一个通知处
                locksize += iBufferSize;
            }
            capturedata = (byte[])capturebuffer.Read(iBufferOffset, typeof(byte), LockFlag.FromWriteCursor, locksize);
            //capturedata = g729.Encode(capturedata);//语音编码
            try
            {
                Client.SendTo(capturedata, epServer);//传送语音
            }
            catch
            {
                 throw new Exception();
            }
            iBufferOffset += capturedata.Length;
            iBufferOffset %= iBufferSize;//取模是因为缓冲区是循环的。
        }


        private int intPosWrite = 0;//内存流中写指针位移
        private int intPosPlay = 0;//内存流中播放指针位移
        private int intNotifySize = 5000;//设置通知大小

        /// <summary>
        /// 从字节数组中获取音频数据,并进行播放
        /// </summary>
        /// <param name="intRecv">字节数组长度</param>
        /// <param name="bytRecv">包含音频数据的字节数组</param>
        public void GetVoiceData(int intRecv, byte[] bytRecv)
        {
            //intPosWrite指示最新的数据写好后的末尾。intPosPlay指示本次播放开始的位置。
            if (intPosWrite + intRecv <= memstream.Capacity)
            {//如果当前写指针所在的位移+将要写入到缓冲区的长度小于缓冲区总大小
                if ((intPosWrite - intPosPlay >= 0 && intPosWrite - intPosPlay < intNotifySize) || (intPosWrite - intPosPlay < 0 && intPosWrite - intPosPlay + memstream.Capacity < intNotifySize))
                {
                    memstream.Write(bytRecv, 0, intRecv);
                    intPosWrite += intRecv;

                }
                else if (intPosWrite - intPosPlay >= 0)
                {//先存储一定量的数据,当达到一定数据量时就播放声音。
                    buffDiscript.BufferBytes = intPosWrite - intPosPlay;//缓冲区大小为播放指针到写指针之间的距离。
                    SecondaryBuffer sec = new SecondaryBuffer(buffDiscript, PlayDev);//建立一个合适的缓冲区用于播放这段数据。
                    memstream.Position = intPosPlay;//先将memstream的指针定位到这一次播放开始的位置
                    sec.Write(0, memstream, intPosWrite - intPosPlay, LockFlag.FromWriteCursor);
                    sec.Play(0, BufferPlayFlags.Default);
                    memstream.Position = intPosWrite;//写完后重新将memstream的指针定位到将要写下去的位置。
                    intPosPlay = intPosWrite;
                }
                else if (intPosWrite - intPosPlay < 0)
                {
                    buffDiscript.BufferBytes = intPosWrite - intPosPlay + memstream.Capacity;//缓冲区大小为播放指针到写指针之间的距离。
                    SecondaryBuffer sec = new SecondaryBuffer(buffDiscript, PlayDev);//建立一个合适的缓冲区用于播放这段数据。
                    memstream.Position = intPosPlay;
                    sec.Write(0, memstream, memstream.Capacity - intPosPlay, LockFlag.FromWriteCursor);
                    memstream.Position = 0;
                    sec.Write(memstream.Capacity - intPosPlay, memstream, intPosWrite, LockFlag.FromWriteCursor);
                    sec.Play(0, BufferPlayFlags.Default);
                    memstream.Position = intPosWrite;
                    intPosPlay = intPosWrite;
                }
            }
            else
            {//当数据将要大于memstream可容纳的大小时
                int irest = memstream.Capacity - intPosWrite;//memstream中剩下的可容纳的字节数。
                memstream.Write(bytRecv, 0, irest);//先写完这个内存流。
                memstream.Position = 0;//然后让新的数据从memstream的0位置开始记录
                memstream.Write(bytRecv, irest, intRecv - irest);//覆盖旧的数据
                intPosWrite = intRecv - irest;//更新写指针位置。写指针指示下一个开始写入的位置而不是上一次结束的位置,因此不用减一
            }
        }

        /// <summary>
        /// 设置音频格式,如采样率等
        /// </summary>
        /// <returns>设置完成后的格式</returns>
        private WaveFormat SetWaveFormat()
        {
            WaveFormat format = new WaveFormat();
            format.FormatTag = WaveFormatTag.Pcm;//设置音频类型
            format.SamplesPerSecond = 11025;//采样率(单位:赫兹)典型值:11025、22050、44100Hz
            format.BitsPerSample = 16;//采样位数
            format.Channels = 1;//声道
            format.BlockAlign = (short)(format.Channels * (format.BitsPerSample / 8));//单位采样点的字节数
            format.AverageBytesPerSecond = format.BlockAlign * format.SamplesPerSecond;

            return format;
            //按照以上采样规格,可知采样1秒钟的字节数为22050*2=44100B 约为 43K
        }

        /// <summary>
        /// 停止语音采集
        /// </summary>
        public void Stop()
        {
            capturebuffer.Stop();
            if (notifyEvent != null)
            {
                notifyEvent.Set();
            }
            if (notifyThread != null && notifyThread.IsAlive == true)
            {
                notifyThread.Abort();
            }
        }
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值