关于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二个数然后加在
窗口的现在的坐标上,就能实现窗口的抖动了。
哈哈,暂时先总结到这,现在去吃饭,回来实现窗口的抖动,加油!!!!