相信我们所有人都使用过或正在使用扣扣和微信。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地址
- 查看消息框
程序