软件工程 2016.6.30 日报

软件工程 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         }

  我将写好的两个程序分别在同一局域网下的两台机子上跑,能够成功实现通信,这为后续进一步扩展功能,实现吐槽墙奠定了一定的基础。

原文地址:https://www.cnblogs.com/fanfan-blogs/p/5631528.html