基于Socket的Winform例子
一、直接上效果图
二、Socket握手
三、服务端
Thread threadWatch = null;// 负责监听客户端的线程 Socket socketWatch = null;// 负责监听客户端的套接字 Socket clientConnection = null;// 负责和客户端通信的套接字 private void btn_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(ipAddress.Text.ToString())) { MessageBox.Show("监听ip地址不能为空!"); return; } if (string.IsNullOrEmpty(port.Text.ToString())) { MessageBox.Show("监听端口不能为空!"); return; } // 定义一个套接字用于监听客户端发来的消息,包含三个参数(ipv4寻址协议,流式连接,tcp协议) socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 服务端发送消息需要一个ip地址和端口号 IPAddress ip = IPAddress.Parse(ipAddress.Text.Trim()); // 把ip地址和端口号绑定在网路节点endport上 IPEndPoint endPort = new IPEndPoint(ip, int.Parse(port.Text.Trim())); // 监听绑定的网路节点 socketWatch.Bind(endPort); // 将套接字的监听队列长度设置限制为0,0表示无限 socketWatch.Listen(0); // 创建一个监听线程 threadWatch = new Thread(WatchConnecting); threadWatch.IsBackground = true; threadWatch.Start(); chatContent.AppendText("成功启动监听!ip:"+ip+",端口:"+port.Text.Trim()+"\r\n"); } /// <summary> /// 监听客户端发来的请求 /// </summary> private void WatchConnecting() { //持续不断监听客户端发来的请求 while (true) { clientConnection = socketWatch.Accept(); chatContent.AppendText("客户端连接成功!"+"\r\n"); // 创建一个通信线程 ParameterizedThreadStart pts = new ParameterizedThreadStart(acceptMsg); Thread thr = new Thread(pts); thr.IsBackground = true; thr.Start(clientConnection); } } /// <summary> /// 接收客户端发来的消息 /// </summary> /// <param name="socket">客户端套接字对象</param> private void acceptMsg(object socket) { Socket socketServer = socket as Socket; while (true) { //创建一个内存缓冲区 其大小为1024*1024字节 即1M byte[] recMsg = new byte[1024 * 1024]; //将接收到的信息存入到内存缓冲区,并返回其字节数组的长度 int length = socketServer.Receive(recMsg); //将机器接受到的字节数组转换为人可以读懂的字符串 string msg = Encoding.UTF8.GetString(recMsg,0,length); chatContent.AppendText("客户端("+GetCurrentTime()+"):"+msg+"\r\n"); } } /// <summary> /// 发送消息到客户端 /// </summary> /// <param name="msg"></param> private void serverSendMsg(string msg) { byte[] sendMsg = Encoding.UTF8.GetBytes(msg); clientConnection.Send(sendMsg); chatContent.AppendText("服务端("+GetCurrentTime()+"):"+msg+"\r\n"); } /// <summary> /// 获取当前系统时间的方法 /// </summary> /// <returns>当前时间</returns> private DateTime GetCurrentTime() { DateTime currentTime = new DateTime(); currentTime = DateTime.Now; return currentTime; }
四、客户端
// 创建一个客户端套接字 Socket clientSocket = null; // 创建一个监听服务端的线程 Thread threadServer = null; private void btn_Click(object sender, EventArgs e) { clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); if (string.IsNullOrEmpty(ipAddress.Text.ToString())) { MessageBox.Show("监听ip地址不能为空!"); return; } if (string.IsNullOrEmpty(port.Text.ToString())) { MessageBox.Show("监听端口不能为空!"); return; } IPAddress ip = IPAddress.Parse(ipAddress.Text.Trim()); IPEndPoint endpoint = new IPEndPoint(ip, int.Parse(port.Text.Trim())); try { //这里客户端套接字连接到网络节点(服务端)用的方法是Connect 而不是Bind clientSocket.Connect(endpoint); } catch { chatContent.AppendText("连接失败!"); } // 创建一个线程监听服务端发来的消息 threadServer = new Thread(recMsg); threadServer.IsBackground = true; threadServer.Start(); } /// <summary> /// 接收服务端发来的消息 /// </summary> private void recMsg() { while (true) //持续监听服务端发来的消息 { //定义一个1M的内存缓冲区 用于临时性存储接收到的信息 byte[] arrRecMsg = new byte[1024 * 1024]; int length = 0; try { //将客户端套接字接收到的数据存入内存缓冲区, 并获取其长度 length = clientSocket.Receive(arrRecMsg); } catch { return; } //将套接字获取到的字节数组转换为人可以看懂的字符串 string strRecMsg = Encoding.UTF8.GetString(arrRecMsg, 0, length); //将发送的信息追加到聊天内容文本框中 chatContent.AppendText("服务端(" + GetCurrentTime() + "):" + strRecMsg + "\r\n"); } } /// <summary> /// 发送消息到服务端 /// </summary> /// <param name="msg"></param> private void clientSendMsg(string msg) { byte[] sendMsg = Encoding.UTF8.GetBytes(msg); clientSocket.Send(sendMsg); chatContent.AppendText("客户端(" + GetCurrentTime() + "):" + msg + "\r\n"); } /// <summary> /// 获取当前系统时间的方法 /// </summary> /// <returns>当前时间</returns> private DateTime GetCurrentTime() { DateTime currentTime = new DateTime(); currentTime = DateTime.Now; return currentTime; }
GitHub源码地址:https://github.com/51042309/Socket