相信我们所有人都使用过或正在使用扣扣和微信。QQ是一款基于互联网的即时通信软件。我们在享受即时通讯的便捷和智能时,是否也想过,QQ、微信的聊天功能是怎么实现的?
功能
我们首先需要知道我们和对方的网络地址,现在主流的ip地址是IPV4和IPV6。
之后我们就可以通过这些地址进行双向通信,实现聊天室的功能。
实现
查看本机IP
打开windows的控制面板(按win +R )

输入cmd
输入ipconfig查看本机IP

发送端
//获取当前IPv4地址 private string GetIpAddress() { string hostName = Dns.GetHostName(); //获取本机名 IPHostEntry localhost = Dns.GetHostByName(hostName); //方法已过期,可以获取IPv4的地址 //IPHostEntry localhost = Dns.GetHostEntry(hostName); //获取IPv6地址 IPAddress localaddr = localhost.AddressList[0]; return localaddr.ToString(); } public void UdpSend() { //Parse()把十进制iP转化成IPAddress类,绑定IP地址和端口 remoteIPEp = new IPEndPoint(IPAddress.Parse("IP地址"), CLIENT_UDP_PORT); //创建发送数据 Socket 对象与数据缓冲区 udpSendDataBuf = new byte[1024]; skUdpSend = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); //为false,等待执行 mreUdpShutDown = new ManualResetEvent(false); mreUdpSend = new ManualResetEvent(false); whUdp = new WaitHandle[2]; whUdp[0] = mreUdpShutDown;//UDP结束命令 whUdp[1] = mreUdpSend; //UDP服务结束命令 int iWaitRetCode; iWaitRetCode = WaitHandle.WaitAny(whUdp, 1000); //等待指定数组中的任意元素接收信号,同时使用 TimeSpan 指定时间间隔 byte[] b_txt; int iByteLen; //满足条件 while (iWaitRetCode != 0) { switch (iWaitRetCode) { case 1://发送数据 b_txt = Encoding.UTF8.GetBytes(strSendTxt); iByteLen = b_txt.Length; //初始化缓存数据 Array.Clear(udpSendDataBuf, iWaitRetCode, iByteLen); //复制数组 Array.Copy(b_txt, udpSendDataBuf, iByteLen); //发送到指定IP skUdpSend.SendTo(udpSendDataBuf, remoteIPEp); //消费掉一次事件 mreUdpSend.Reset(); break; case WaitHandle.WaitTimeout://超时 break; } //继续下次事件检测 iWaitRetCode = WaitHandle.WaitAny(whUdp, 1000); } skUdpSend.Close(); skUdpSend = null; } #endregion UDP发送线程线程 public static string strSendTxt; private void button1_Click(object sender, EventArgs e) { mreUdpShutDown.Set(); } private void button2_Click(object sender, EventArgs e) { strSendTxt = GetIpAddress() +":"+ textBox1.Text + "\r\n"; mreUdpSend.Set(); } private void liaotian_Load(object sender, EventArgs e) { //线程开始 ThreadStart theStart = new ThreadStart(UdpSend); Thread theThr = new Thread(theStart); theThr.Start(); } private void liaotian_FormClosing(object sender, FormClosingEventArgs e) { mreUdpShutDown.Set(); }
复制代码namespace FormUdpSend{ public partial class send : Form { public send() { InitializeComponent(); } #region UDP发送线程 public static int iUdpRecvPkgLen; public static Socket skUdpSend; public static byte[] udpSendDataBuf; public static IPEndPoint remoteIPEp; //IP地址和端口的绑定 public static int CLIENT_UDP_PORT = 0x5555; //分配给 Port属性,例子用ipv4 public static ManualResetEvent mreUdpShutDown;//UDP结束命令 public static ManualResetEvent mreUdpSend;//UDP发送命令 public static WaitHandle[] whUdp; //UDP相关句柄 //获取当前IPv4地址 private string GetIpAddress() { string hostName = Dns.GetHostName(); //获取本机名 IPHostEntry localhost = Dns.GetHostByName(hostName); //方法已过期,可以获取IPv4的地址 //IPHostEntry localhost = Dns.GetHostEntry(hostName); //获取IPv6地址 IPAddress localaddr = localhost.AddressList[0]; return localaddr.ToString(); } public void UdpSend() { //Parse()把十进制iP转化成IPAddress类,绑定IP地址和端口 remoteIPEp = new IPEndPoint(IPAddress.Parse("169.254.7.216"), CLIENT_UDP_PORT); //创建发送数据 Socket 对象与数据缓冲区 udpSendDataBuf = new byte[1024]; skUdpSend = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); //为false,等待执行 mreUdpShutDown = new ManualResetEvent(false); mreUdpSend = new ManualResetEvent(false); whUdp = new WaitHandle[2]; whUdp[0] = mreUdpShutDown;//UDP结束命令 whUdp[1] = mreUdpSend; //UDP服务结束命令 int iWaitRetCode; iWaitRetCode = WaitHandle.WaitAny(whUdp, 1000); //等待指定数组中的任意元素接收信号,同时使用 TimeSpan 指定时间间隔 byte[] b_txt; int iByteLen; //满足条件 while (iWaitRetCode != 0) { switch (iWaitRetCode) { case 1://发送数据 b_txt = Encoding.UTF8.GetBytes(strSendTxt); iByteLen = b_txt.Length; //初始化缓存数据 Array.Clear(udpSendDataBuf, iWaitRetCode, iByteLen); //复制数组 Array.Copy(b_txt, udpSendDataBuf, iByteLen); //发送到指定IP skUdpSend.SendTo(udpSendDataBuf, remoteIPEp); //消费掉一次事件 mreUdpSend.Reset(); break; case WaitHandle.WaitTimeout://超时 break; } //继续下次事件检测 iWaitRetCode = WaitHandle.WaitAny(whUdp, 1000); } skUdpSend.Close(); skUdpSend = null; } #endregion UDP发送线程线程 public static string strSendTxt; private void button1_Click(object sender, EventArgs e) { mreUdpShutDown.Set(); } private void button2_Click(object sender, EventArgs e) { strSendTxt = GetIpAddress() +":"+ textBox1.Text + "\r\n"; mreUdpSend.Set(); } private void Form1_Load(object sender, EventArgs e) { //线程开始 ThreadStart theStart = new ThreadStart(UdpSend); Thread theThr = new Thread(theStart); theThr.Start(); } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { mreUdpShutDown.Set(); } } }
复制代码- 在发送端程序中输入IP地址
- 运行发送端程序,在输入框中输入要发送的消息
- 运行接收端信息
- 输入IP地址
- 查看消息框
程序