微信QQ聊天是怎么实现的?原来这么简单!!!

Posted 跋扈洋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信QQ聊天是怎么实现的?原来这么简单!!!相关的知识,希望对你有一定的参考价值。

QQ聊天是怎么实现的?原来这么简单!!!

需求

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

功能

我们首先需要知道我们和对方的网络地址,现在主流的ip地址是IPV4和IPV6。
之后我们就可以通过这些地址进行双向通信,实现聊天室的功能。

实现

查看本机IP

  1. 打开windows的控制面板(按win +R )
  2. 输入cmd
  3. 输入ipconfig查看本机IP
    1

发送端

本位置的程序主要为了让大家理解是怎么制作发送端的程序。具体完整的项目工程文件在下方会有所有的程序供大家下载。

        //获取当前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();
        }
    }
}

完整程序

使用流程

  1. 在发送端程序中输入IP地址
  2. 运行发送端程序,在输入框中输入要发送的消息
  3. 运行接收端信息
  4. 输入IP地址
  5. 查看消息框

运行结果


程序

后续

如果想了解更多物联网、智能家居项目知识,可以关注我的程序设计专栏
或者关注公众号。
在这里插入图片描述

编写不易,感谢支持。

以上是关于微信QQ聊天是怎么实现的?原来这么简单!!!的主要内容,如果未能解决你的问题,请参考以下文章

Android实现类似QQ聊天的功能 怎么实现

关于Java聊天收到消息自动弹出窗口代码

习惯了微信聊天,利用WebSocket手动实现个聊天功能怎么样?

微信代码怎么用

iOS 类似微信,QQ聊天界面的气泡聊天简单实现Demo

java聊天功能怎么做的?有没有知道的可以指导一下吗?