关于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二个数然后加在

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

 

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

 

posted @ 2014-07-18 12:06  火悬崖  阅读(2066)  评论(1编辑  收藏  举报