首页 > 代码库 > 关于Socket编写简单聊天工具的总结(原创)

关于Socket编写简单聊天工具的总结(原创)

       这段时间再看socket编程,虽然现在是刚刚接触,但是还是忍不住想写一篇总结,来激励自己努力学习,写的不好的地方,还请大家指教啊!

  下面针对一个简单的发送消息和文件的程序说说吧。   首先是服务器需要准备二个Socket和二个Thread如下:

//和客户机进行通信        private Socket sckCommit;        //监听客户机        private Socket sckListen;        private Thread thdListen;        private Thread thdCommit;

 对客户机的监听和通信放在二个单独的线程中,服务端的简单界面如下:

点击启动按钮时调用下面的函数:

#region 初始化监听        //初始化监听        public void Listen()        {            try            {                string ip = txtIp.Text.Trim();                string port = txtPort.Text.Trim();                //创建IP地址                IPAddress ipaddress = IPAddress.Parse(ip);                //创建IP节点                IPEndPoint endpoint = new IPEndPoint(ipaddress, int.Parse(port));                //创建套接字                sckListen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);                //绑定IP节点                sckListen.Bind(endpoint);                sckListen.Listen(10);//10为同时最大连接数                //在单独的线程里监听                thdListen = new Thread(Watch);                thdListen.IsBackground = true;                thdListen.Start();                ShowMsg("服务器启动.................");            }            catch (Exception ex)            {                ShowErr(ex);            }        }         #endregion        #region 在单独的线程里监听端口        public void Watch()        {            while (true)            {                try                {                   sckCommit= sckListen.Accept();                   thdCommit = new Thread(ReceiveMsg);                   thdCommit.IsBackground = true;                   thdCommit.Start();                   ShowMsg("监听到连接");                }                catch (Exception ex)                {                    ShowErr(ex);                    break;                }            }        }         #endregion

启动服务器进行监听,程序运行到sckCommit= sckListen.Accept();时,由于Accept();阻塞运行等待客户的连接,然后开始启动接受消息的线程。

public void ReceiveMsg()        {            while (true)            {                try                {                    byte[] b = new byte[1024 * 1024 * 4];                    int size = sckCommit.Receive(b);                    string msg = Encoding.UTF8.GetString(b, 0, size);                    ShowMsg(msg);                }                catch (Exception ex)                {                    ShowErr(ex);                    break;                }            }        }

对于客户端,首先需要主动与服务器进行连接,客户端截图如下:

点击连接时,调用下面的函数:

public void Connnetion()        {            try            {                sckConnection = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);                //创建ip地址                IPAddress ipaddress = IPAddress.Parse(txtIp.Text.Trim());                //创建IP节点                IPEndPoint endpoint = new IPEndPoint(ipaddress, int.Parse(txtPort.Text.Trim()));                //连接ip地址为txtIp.Text.Trim()Port为txtPort.Text.Trim()                sckConnection.Connect(endpoint);                thdConnection = new Thread(ReceiveMsg);                thdConnection.IsBackground = true;                thdConnection.Start();            }            catch (Exception ex)            {                ShowErr(ex);            }        }        public void ReceiveMsg()        {            while (true)            {                try                {                    byte[] byteMsg = new byte[1024 * 1024 * 4];                    int length = sckConnection.Receive(byteMsg);                    if (byteMsg[0] == 0)                    {                        string strMsg = Encoding.UTF8.GetString(byteMsg, 1, length-1);                        ShowMsg(strMsg);                    }                    else if (byteMsg[0] == 1)                    {                        //OpenFileDialog sfd = new OpenFileDialog();                        //if (sfd.ShowDialog() == DialogResult.OK)                        //{                        //    string savePath = sfd.FileName;                            using (FileStream fs = new FileStream(@"1.txt", FileMode.Create))                            {                                fs.Write(byteMsg, 1, length - 1);                                ShowMsg("文件保存成功:");                            }                        //}                    }                    else                    {                        ShowMsg("sdf");                    }                                                        }                catch (Exception ex)                {                    ShowErr(ex);                    break;                }            }        }

这样就能接受服务器发来的数据了,为了节省篇幅,其他重复性的代码就不粘上来了。

 

还需要注意的是,如何区别发送的是文件还是消息还是窗口抖动,我的做法就是在发送的字节数组的第一位做一个标记位,

如果是0怎发送的是字符串,如果是1则发送的是文件,如果是2则发送的是窗口抖动。

对于文件和字符串上面的代码都有,窗口抖动现在还没实现,我的思路是用一个for循环,循环10-30次,每一次都用随机数生成x,y二个数然后加在

窗口的现在的坐标上,就能实现窗口的抖动了。

 

哈哈,暂时先总结到这,现在去吃饭,回来实现窗口的抖动,加油!!!!