需求
相信我们所有人都使用过或正在使用扣扣和微信。QQ是一款基于互联网的即时通信软件。我们在享受即时通讯的便捷和智能时,是否也想过,QQ、微信的聊天功能是怎么实现的?

功能
我们首先需要知道我们和对方的网络地址,现在主流的ip地址是IPV4和IPV6。
之后我们就可以通过这些地址进行双向通信,实现聊天室的功能。
实现
查看本机IP
打开windows的控制面板(按win +R )
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NjI5MTA5,size_16,color_FFFFFF,t_70#pic_center.jpg
输入cmd
输入ipconfig查看本机IP
20210604105632817.jpg
发送端
  1.         //获取当前IPv4地址
  2.         private string GetIpAddress()
  3.         {
  4.             string hostName = Dns.GetHostName();   //获取本机名
  5.             IPHostEntry localhost = Dns.GetHostByName(hostName);    //方法已过期,可以获取IPv4的地址
  6.                                                                     //IPHostEntry localhost = Dns.GetHostEntry(hostName);   //获取IPv6地址
  7.             IPAddress localaddr = localhost.AddressList[0];
  8.             return localaddr.ToString();
  9.         }
  10.         public void UdpSend()
  11.         {
  12.             //Parse()把十进制iP转化成IPAddress类,绑定IP地址和端口
  13.             remoteIPEp = new IPEndPoint(IPAddress.Parse("IP地址"), CLIENT_UDP_PORT);
  14.             //创建发送数据 Socket 对象与数据缓冲区
  15.             udpSendDataBuf = new byte[1024];
  16.             skUdpSend = new Socket(AddressFamily.InterNetwork,
  17.             SocketType.Dgram, ProtocolType.Udp);
  18.             //为false,等待执行
  19.             mreUdpShutDown = new ManualResetEvent(false);
  20.             mreUdpSend = new ManualResetEvent(false);
  21.             whUdp = new WaitHandle[2];
  22.             whUdp[0] = mreUdpShutDown;//UDP结束命令
  23.             whUdp[1] = mreUdpSend; //UDP服务结束命令
  24.             int iWaitRetCode;
  25.             iWaitRetCode = WaitHandle.WaitAny(whUdp, 1000);   //等待指定数组中的任意元素接收信号,同时使用 TimeSpan 指定时间间隔
  26.             byte[] b_txt;
  27.             int iByteLen;
  28.             //满足条件
  29.             while (iWaitRetCode != 0)
  30.             {
  31.                 switch (iWaitRetCode)
  32.                 {
  33.                     case 1://发送数据
  34.                         b_txt = Encoding.UTF8.GetBytes(strSendTxt);
  35.                         iByteLen = b_txt.Length;
  36.                         //初始化缓存数据
  37.                         Array.Clear(udpSendDataBuf, iWaitRetCode, iByteLen);
  38.                         //复制数组
  39.                         Array.Copy(b_txt, udpSendDataBuf, iByteLen);
  40.                         //发送到指定IP
  41.                         skUdpSend.SendTo(udpSendDataBuf, remoteIPEp);
  42.                         //消费掉一次事件
  43.                         mreUdpSend.Reset();
  44.                         break;
  45.                     case WaitHandle.WaitTimeout://超时
  46.                         break;
  47.                 }
  48.                 //继续下次事件检测
  49.                 iWaitRetCode = WaitHandle.WaitAny(whUdp, 1000);
  50.             }
  51.             skUdpSend.Close();
  52.             skUdpSend = null;
  53.         }
  54.         #endregion    UDP发送线程线程
  55.         public static string strSendTxt;
  56.         private void button1_Click(object sender, EventArgs e)
  57.         {
  58.             mreUdpShutDown.Set();
  59.         }
  60.         private void button2_Click(object sender, EventArgs e)
  61.         {
  62.             strSendTxt = GetIpAddress() +":"+ textBox1.Text + "\r\n";
  63.             mreUdpSend.Set();
  64.         }
  65.         private void liaotian_Load(object sender, EventArgs e)
  66.         {
  67.             //线程开始
  68.             ThreadStart theStart = new ThreadStart(UdpSend);
  69.             Thread theThr = new Thread(theStart);
  70.             theThr.Start();
  71.         }
  72.         private void liaotian_FormClosing(object sender, FormClosingEventArgs e)
  73.         {
  74.             mreUdpShutDown.Set();
  75.         }
接收端
  1. namespace FormUdpSend
  2. {
  3.     public partial class send : Form
  4.     {
  5.         public send()
  6.         {
  7.             InitializeComponent();
  8.         }
  9.         #region  UDP发送线程
  10.         public static int iUdpRecvPkgLen;
  11.         public static Socket skUdpSend;
  12.         public static byte[] udpSendDataBuf;
  13.         public static IPEndPoint remoteIPEp;  //IP地址和端口的绑定
  14.         public static int CLIENT_UDP_PORT = 0x5555;  //分配给 Port属性,例子用ipv4
  15.         public static ManualResetEvent mreUdpShutDown;//UDP结束命令
  16.         public static ManualResetEvent mreUdpSend;//UDP发送命令
  17.         public static WaitHandle[] whUdp;  //UDP相关句柄
  18.         //获取当前IPv4地址
  19.         private string GetIpAddress()
  20.         {
  21.             string hostName = Dns.GetHostName();   //获取本机名
  22.             IPHostEntry localhost = Dns.GetHostByName(hostName);    //方法已过期,可以获取IPv4的地址
  23.                                                                     //IPHostEntry localhost = Dns.GetHostEntry(hostName);   //获取IPv6地址
  24.             IPAddress localaddr = localhost.AddressList[0];
  25.             return localaddr.ToString();
  26.         }
  27.         public void UdpSend()
  28.         {
  29.             //Parse()把十进制iP转化成IPAddress类,绑定IP地址和端口
  30.             remoteIPEp = new IPEndPoint(IPAddress.Parse("169.254.7.216"), CLIENT_UDP_PORT);
  31.             //创建发送数据 Socket 对象与数据缓冲区
  32.             udpSendDataBuf = new byte[1024];
  33.             skUdpSend = new Socket(AddressFamily.InterNetwork,
  34.             SocketType.Dgram, ProtocolType.Udp);
  35.             //为false,等待执行
  36.             mreUdpShutDown = new ManualResetEvent(false);
  37.             mreUdpSend = new ManualResetEvent(false);
  38.             whUdp = new WaitHandle[2];
  39.             whUdp[0] = mreUdpShutDown;//UDP结束命令
  40.             whUdp[1] = mreUdpSend; //UDP服务结束命令
  41.             int iWaitRetCode;
  42.             iWaitRetCode = WaitHandle.WaitAny(whUdp, 1000);   //等待指定数组中的任意元素接收信号,同时使用 TimeSpan 指定时间间隔
  43.             byte[] b_txt;
  44.             int iByteLen;
  45.             //满足条件
  46.             while (iWaitRetCode != 0)
  47.             {
  48.                 switch (iWaitRetCode)
  49.                 {
  50.                     case 1://发送数据
  51.                         b_txt = Encoding.UTF8.GetBytes(strSendTxt);
  52.                         iByteLen = b_txt.Length;
  53.                         //初始化缓存数据
  54.                         Array.Clear(udpSendDataBuf, iWaitRetCode, iByteLen);
  55.                         //复制数组
  56.                         Array.Copy(b_txt, udpSendDataBuf, iByteLen);
  57.                         //发送到指定IP
  58.                         skUdpSend.SendTo(udpSendDataBuf, remoteIPEp);
  59.                         //消费掉一次事件
  60.                         mreUdpSend.Reset();
  61.                         break;
  62.                     case WaitHandle.WaitTimeout://超时
  63.                         break;
  64.                 }
  65.                 //继续下次事件检测
  66.                 iWaitRetCode = WaitHandle.WaitAny(whUdp, 1000);
  67.             }
  68.             skUdpSend.Close();
  69.             skUdpSend = null;
  70.         }
  71.         #endregion    UDP发送线程线程
  72.         public static string strSendTxt;
  73.         private void button1_Click(object sender, EventArgs e)
  74.         {
  75.             mreUdpShutDown.Set();
  76.         }
  77.         private void button2_Click(object sender, EventArgs e)
  78.         {
  79.             strSendTxt = GetIpAddress() +":"+ textBox1.Text + "\r\n";
  80.             mreUdpSend.Set();
  81.         }
  82.         private void Form1_Load(object sender, EventArgs e)
  83.         {
  84.             //线程开始
  85.             ThreadStart theStart = new ThreadStart(UdpSend);
  86.             Thread theThr = new Thread(theStart);
  87.             theThr.Start();
  88.         }
  89.         private void Form1_FormClosing(object sender, FormClosingEventArgs e)
  90.         {
  91.             mreUdpShutDown.Set();
  92.         }
  93.     }
  94. }
使用流程

  • 在发送端程序中输入IP地址
  • 运行发送端程序,在输入框中输入要发送的消息
  • 运行接收端信息
  • 输入IP地址
  • 查看消息框
运行结果

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ0NjI5MTA5,size_16,color_FFFFFF,t_70#pic_center.jpg
程序