软件工程 2016.6.30 日报
今天主要学习的内容是C# socket网络编程中的TCP通讯技术。socket编程的原理如下:
在服务端的处理流程为:
(1)建立服务器端的Socket,开始侦听整个网络中的连接请求。
(2)当检测到来自客户端的连接请求时,向客户端发送收到连接请求的信息,并建立与客户端之间的连接。
(3)当完成通信后,服务器关闭与客户端的Socket连接。
在服务端的处理流程为:
(1)建立客户端的Socket,确定要连接的服务器的主机名和端口。
(2)发送连接请求到服务器,并等待服务器的回馈信息。
(3)连接成功后,与服务器进行数据的交互。
(4)数据处理完毕后,关闭自身的Socket连接。
我自己也写了一个小的demo完成简单的通信工作,同时将前天学习的多线程的知识也结合到了demo中,实现了多线程的socket通信。
服务器端核心的代码如下:
1 #region ---------- 开启服务器 ---------- 2 /// <summary> 3 /// 开启服务器 4 /// </summary> 5 public void StartServer() 6 { 7 //创建负责监听的套接字,参数使用IPv4寻址协议,使用流式连接,使用TCP协议传输数据 8 socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 9 10 //创建一个绑定IP和port的网络节点对象 11 IPAddress ipAddress = IPAddress.Parse(ipAddr); 12 IPEndPoint endPoint = new IPEndPoint(ipAddress, port); 13 14 try 15 { 16 //将监听socket绑定到创建的网络节点 17 socketWatch.Bind(endPoint); 18 19 //设置监听等待队列的长度 20 socketWatch.Listen(20); 21 22 //创建负责监听的线程,并传入监听方法 23 threadWatch = new Thread(WatchConnection); 24 //设置为后台线程 25 threadWatch.IsBackground = true; 26 //开启线程 27 threadWatch.Start(); 28 29 return; 30 } 31 catch (SocketException se) 32 { 33 Console.WriteLine("【错误】" + se.Message); 34 return; 35 } 36 catch (Exception e) 37 { 38 Console.WriteLine("【错误】" + e.Message); 39 return; 40 } 41 } 42 #endregion 43 44 /// <summary> 45 /// 监听客户端请求 46 /// </summary> 47 private void WatchConnection() 48 { 49 //持续监听请求 50 while (true) 51 { 52 Socket socketConnection = null; 53 try 54 { 55 //监听请求,如果有新请求则返回一个socket 56 socketConnection = socketWatch.Accept(); 57 string socketKey = socketConnection.RemoteEndPoint.ToString(); 58 59 60 //将每个新产生的socket存起来,以客户端IP:端口作为key 61 dictSocket.Add(socketKey, socketConnection); 62 63 Console.WriteLine("用户IP : {0} 已连接...", socketKey); 64 65 //为每个服务端通信socket创建一个单独的通信线程,负责调用通信socket的Receive方法,监听客户端发来的数据 66 //创建通信线程 67 Thread threadCommunicate = new Thread(ReceiveMsg); 68 threadCommunicate.IsBackground = true; 69 threadCommunicate.Start(socketConnection); 70 71 dictThread.Add(socketKey, threadCommunicate); 72 73 } 74 catch (SocketException se) 75 { 76 Console.WriteLine("【错误】" + se.Message); 77 return; 78 } 79 catch (Exception e) 80 { 81 Console.WriteLine("【错误】" + e.Message); 82 return; 83 } 84 } 85 } 86 #endregion 87 88 /// <summary> 89 /// 服务端监听客户发来的数据 90 /// </summary> 91 private void ReceiveMsg(object socketClientPara) 92 { 93 Socket socketClient = socketClientPara as Socket; 94 95 while (true) 96 { 97 // 定义一个接收消息用的缓冲区 98 byte[] msgReceiver = new byte[1024 * 1024 * 2]; 99 100 // 接收消息的长度 101 int length = -1; 102 103 try 104 { 105 length = socketClient.Receive(msgReceiver); 106 } 107 catch (SocketException se) 108 { 109 string socketKey = socketClient.RemoteEndPoint.ToString(); 110 Console.WriteLine("【错误】" + socketKey + " 接收消息异常 错误信息:" + se.Message); 111 } 112 catch (Exception e) 113 { 114 Console.WriteLine("【错误】" + e.Message); 115 return; 116 } 117 string sendMsg = Encoding.UTF8.GetString(msgReceiver, 0, length); 118 Console.WriteLine("收到:{0}", sendMsg) ; 119 }120 }
客户端的核心代码如下:
1 #region ---------- 开启客户机 ---------- 2 /// <summary> 3 /// 开启客户端 4 /// </summary> 5 public void StartClient() 6 { 7 //创建一个绑定IP和port的网络节点对象 8 IPAddress ipAddress = IPAddress.Parse(ipAddr); 9 IPEndPoint endPoint = new IPEndPoint(ipAddress, port); 10 11 socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 12 13 try 14 { 15 //连接服务器 16 socketClient.Connect(endPoint); 17 18 threadClient = new Thread(ReceiveMsg); 19 threadClient.IsBackground = true; 20 threadClient.Start(); 21 } 22 catch (SocketException se) 23 { 24 Console.WriteLine("【错误】连接服务器异常:" + se.Message); 25 return; 26 } 27 catch (Exception e) 28 { 29 Console.WriteLine("【错误】连接服务器异常:" + e.Message); 30 return; 31 } 32 } 33 #endregion 34 35 #region ---------- 接收消息 ---------- 36 /// <summary> 37 /// 接收消息 38 /// </summary> 39 private void ReceiveMsg() 40 { 41 while (true) 42 { 43 // 定义一个缓冲区保存接收的消息 44 byte[] arrMsg = new byte[1024 * 1024 * 2]; 45 46 // 保存数据长度 47 int length = -1; 48 49 try 50 { 51 // 获取信息 52 length = socketClient.Receive(arrMsg); 53 54 // 解析字符串 55 string msgReceive = Encoding.UTF8.GetString(arrMsg); 56 57 Console.WriteLine("收到:{0}",msgReceive); 58 } 59 catch (SocketException se) 60 { 61 Console.WriteLine("【错误】接收消息异常:" + se.Message); 62 return; 63 } 64 catch (Exception e) 65 { 66 Console.WriteLine("【错误】接收消息异常:" + e.Message); 67 return; 68 } 69 } 70 } 71 #endregion 72 73 #region ---------- 发送消息 ---------- 74 public void SendMsg(string msg) 75 { 76 byte[] arrMsg = Encoding.UTF8.GetBytes(msg); 77 78 try 79 { 80 socketClient.Send(sendArrMsg); 81 82 Console.WriteLine("我:{0}", msg); 83 } 84 catch (SocketException se) 85 { 86 Console.WriteLine("【错误】发送消息异常:" + se.Message); 87 return; 88 } 89 catch (Exception e) 90 { 91 Console.WriteLine("【错误】发送消息异常:" + e.Message); 92 return; 93 } 94 95 }
我将写好的两个程序分别在同一局域网下的两台机子上跑,能够成功实现通信,这为后续进一步扩展功能,实现吐槽墙奠定了一定的基础。
时间: 2024-10-12 23:28:35