1 2 |
//通知一个或多个正在等待的线程已发生事件。 ManualResetEvent manager = new ManualResetEvent(false); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
//负责监听的套接字 private Socket socketServer; /// <summary> /// 启动服务 /// </summary> private void CreateSocketService() { try { //获取IP var address = IPAddress.Parse(txtIP.Text.Trim()); //创建一个包含ip port 的网络节点对象 var ipPoint = new IPEndPoint(address, Convert.ToInt32(txtPort.Text.Trim())); //创建一个套接字socket,参数(IP4寻址协议,流式连接,使用TCP协议传输数据) socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //将负责监听的套接字绑定到唯一的IP和端口上 socketServer.Bind(ipPoint); //设置监听队列的长度,同时100个队列 socketServer.Listen(100); //线程开始监听客户端的请求 threadService = new Thread(StartSocketService); //设置线程为后台线程 threadService.IsBackground = true; //启动线程 threadService.Start(); //显示消息 ShowMsg("服务器监听开启成功!"); } catch (Exception e) { ShowMsg(e.Message); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
/// <summary> /// 启动服务监听 /// </summary> private void StartSocketService() { while (true) { try { //将事件状态设置为非终止状态,导致线程阻止 manager.Reset(); //开始监听客户端的连接请求 var args = new SocketAsyncEventArgs(); args.Completed += args_Completed; socketServer.AcceptAsync(args); //WaitHandle receives a signal." data-guid="dd8c3ab0d5ce03487bc8a650ef1c15c8">阻止当前线程,直到当前 WaitHandle 收到信号。 manager.WaitOne(); } catch (Exception ex) { ShowMsg(ex.Message); break; } } } |
1 2 3 4 5 6 7 8 9 |
void args_Completed(object sender, SocketAsyncEventArgs e) { //监听完成客户端的请求,一但监听到返回新的套接字 var clientSocket = e.AcceptSocket; //启动线程获取客户端发来的消息 if (clientSocket == null) return; //开始接受消息....... //该函数未写完,第二篇补全 } |
1 2 3 4 5 |
void ShowMsg(string message) { //显示消息 txtConneMsg.AppendText("\r\n" + DateTime.Now + "\r\n\r\n" + message + "\r\n"); } |
ok 服务监听就启动成功了,正等待客户端连接。
1 |
ManualResetEvent reviceManager = new ManualResetEvent(false); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public void args_Completed(object sender, SocketAsyncEventArgs e) { //监听完成客户端的请求,一但监听到返回新的套接字 var clientSocket = e.AcceptSocket; if (clientSocket == null) return; //启动线程获取客户端发来的消息 //这部分为接收消息 var t = new Thread(GetClientMsg); //设置线程为后台线程 t.IsBackground = true; //启动线程 t.Start(clientSocket); //显示信息 ShowMsg(clientSocket.RemoteEndPoint + "上线了"); //将事件状态设置为终止状态,允许一个或多个等待线程继续 manager.Set(); } |
建议对照 C# Socket基础(一)之启动异步服务侦听 来看。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
private void GetClientMsg(object socket) { var socketClient = socket as Socket; if (socketClient == null) return; while (true) { try { reviceManager.Reset(); var bytes = new byte[1024 * 1024 * 4]; var receiveArgs = new SocketAsyncEventArgs(); //设置缓冲区 receiveArgs.SetBuffer(bytes, 0, bytes.Length); receiveArgs.Completed += receiveArgs_Completed; //开始异步接收 socketClient.ReceiveAsync(receiveArgs); reviceManager.WaitOne(); } catch (Exception ex) { //显示异常消息 ShowMsg(ex.Message); } } } |
接收消息完成回调事件
1 2 3 4 5 6 7 |
void receiveArgs_Completed(object sender, SocketAsyncEventArgs e) { var socketClient = sender as Socket; var bytes = e.Buffer; ShowMsg(socketClient.RemoteEndPoint + "说:" + System.Text.Encoding.UTF8.GetString(bytes)); reviceManager.Set(); } |
又与大家见面,看不懂的随时问。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
private Thread threadClient;//客户端线程 private Socket socketClient;//客户端套接字 /// <summary> /// 创建套接字连接到服务端 /// </summary> private void CreateSocketConnection() { try { //创建一个客户端的套接字 参数(IP4寻址协议,流连接方式,TCP数据传输协议) socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //获取IP IPAddress address = IPAddress.Parse(txtIP.Text.Trim()); //创建一个包含IP和端口号的网络节点对象 IPEndPoint ipPoint = new IPEndPoint(address, Convert.ToInt32(txtPort.Text.Trim())); // 连接服务端 socketClient.Connect(ipPoint); //创建一个线程,接受服务端发来的数据 threadClient = new Thread(ReceiveService); //设置线程为后台线程 threadClient.IsBackground = true; //启动线程连接服务端 threadClient.Start(); //显示消息 ShowMsg("与服务器" + txtIP.Text.Trim() + ":" + txtPort.Text + "成功建立连接!"); } catch (Exception) { ShowMsg(txtIP.Text.Trim() + ":" + txtPort.Text + "服务器未启动!"); } } |
客户端接收消息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
private void ReceiveService() { while (true) { try { int num = -1; var b = new byte[1024 * 1024 * 4]; int length = socketClient.Receive(b); var msg = System.Text.Encoding.UTF8.GetString(b,0,length); ShowMsg(socketClient.RemoteEndPoint.ToString() + "对您: " + msg); } catch (Exception ex) { ShowMsg(ex.Message); break; } } } |
1 2 3 4 |
private void ShowMsg(string msg) { txtConneMsg.AppendText("\r\n" + DateTime.Now + "\r\n\r\n" + msg + "\r\n"); } |
客户端:
服务器:
客户端接收到消息:
private Socket socketClient;//客户端套接字,关于实例化请参考C# Socket基础(三)之客户端连接服务器和接收消息
客户端发送消息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
/// <summary> /// 发送数据到服务端 /// </summary> private void Send() { if (socketClient == null) { ShowMsg("服务器未启动!"); return; } byte[] b = System.Text.Encoding.UTF8.GetBytes(txtSend.Text.Trim()); //客户端向服务器发送消息 socketClient.Send(b); //清空文本 ShowMsg("您对" + socketClient.RemoteEndPoint.ToString() + "说:" + txtSend.Text.Trim()); txtSend.Text = ""; } |
关于 ShowMsg(string message);是自定义的函数,在C# Socket基础(一)之启动异步服务侦听
好了,到这里就要告一段落了,实现了基本的客户端和服务器采用TCP协议通信。
看看效果吧:
客户端:
服务器:
from:https://www.cnblogs.com/aaa6818162/p/3862159.html