c#Socket Tcp服务端编程

转自  https://www.cnblogs.com/kellen451/p/7127670.html

  1 /*
  2  *
  3  * 该类用于管理tcp连接通讯
  4  * 
  5  */
  6 
  7 using System;
  8 using System.Collections.Generic;
  9 using System.Net.Sockets;
 10 using System.Threading;
 11 using System.Net;
 12 
 13 namespace Communication
 14 {
 15     /// <summary>
 16     /// 服务端
 17     /// </summary>
 18     public class MyTcpServer
 19     {
 20 
 21         private Socket ServerSocket = null;//服务端  
 22         public Dictionary<string, MySession> dic_ClientSocket = new Dictionary<string, MySession>();//tcp客户端字典
 23         private Dictionary<string, Thread> dic_ClientThread = new Dictionary<string, Thread>();//线程字典,每新增一个连接就添加一条线程
 24         private bool Flag_Listen = true;//监听客户端连接的标志
 25 
 26         /// <summary>
 27         /// 启动服务
 28         /// </summary>
 29         /// <param name="port">端口号</param>
 30         public bool OpenServer(int port)
 31         {
 32             try
 33             {
 34                 Flag_Listen = true;
 35                 // 创建负责监听的套接字,注意其中的参数;
 36                 ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 37                 // 创建包含ip和端口号的网络节点对象;
 38                 IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, port);
 39                 try
 40                 {
 41                     // 将负责监听的套接字绑定到唯一的ip和端口上;
 42                     ServerSocket.Bind(endPoint);
 43                 }
 44                 catch
 45                 {
 46                     return false;
 47                 }
 48                 // 设置监听队列的长度;
 49                 ServerSocket.Listen(100);
 50                 // 创建负责监听的线程;
 51                 Thread Thread_ServerListen = new Thread(ListenConnecting);
 52                 Thread_ServerListen.IsBackground = true;
 53                 Thread_ServerListen.Start();
 54 
 55                 return true;
 56             }
 57             catch
 58             {
 59                 return false;
 60             }
 61         }
 62         /// <summary>
 63         /// 关闭服务
 64         /// </summary>
 65         public void CloseServer()
 66         {
 67             lock (dic_ClientSocket)
 68             {
 69                 foreach (var item in dic_ClientSocket)
 70                 {
 71                     item.Value.Close();//关闭每一个连接
 72                 }
 73                 dic_ClientSocket.Clear();//清除字典
 74             }
 75             lock (dic_ClientThread)
 76             {
 77                 foreach (var item in dic_ClientThread)
 78                 {
 79                     item.Value.Abort();//停止线程
 80                 }
 81                 dic_ClientThread.Clear();
 82             }
 83             Flag_Listen = false;
 84             //ServerSocket.Shutdown(SocketShutdown.Both);//服务端不能主动关闭连接,需要把监听到的连接逐个关闭
 85             if (ServerSocket != null)
 86                 ServerSocket.Close();
 87 
 88         }
 89         /// <summary>
 90         /// 监听客户端请求的方法;
 91         /// </summary>
 92         private void ListenConnecting()
 93         {
 94             while (Flag_Listen)  // 持续不断的监听客户端的连接请求;
 95             {
 96                 try
 97                 {
 98                     Socket sokConnection = ServerSocket.Accept(); // 一旦监听到一个客户端的请求,就返回一个与该客户端通信的 套接字;
 99                     // 将与客户端连接的 套接字 对象添加到集合中;
100                     string str_EndPoint = sokConnection.RemoteEndPoint.ToString();
101                     MySession myTcpClient = new MySession() { TcpSocket = sokConnection };
102                     //创建线程接收数据
103                     Thread th_ReceiveData = new Thread(ReceiveData);
104                     th_ReceiveData.IsBackground = true;
105                     th_ReceiveData.Start(myTcpClient);
106                     //把线程及客户连接加入字典
107                     dic_ClientThread.Add(str_EndPoint, th_ReceiveData);
108                     dic_ClientSocket.Add(str_EndPoint, myTcpClient);
109                 }
110                 catch
111                 {
112 
113                 }
114                 Thread.Sleep(200);
115             }
116         }
117         /// <summary>
118         /// 接收数据
119         /// </summary>
120         /// <param name="sokConnectionparn"></param>
121         private void ReceiveData(object sokConnectionparn)
122         {
123             MySession tcpClient = sokConnectionparn as MySession;
124             Socket socketClient = tcpClient.TcpSocket;
125             bool Flag_Receive = true;
126 
127             while (Flag_Receive)
128             {
129                 try
130                 {
131                     // 定义一个2M的缓存区;
132                     byte[] arrMsgRec = new byte[1024 * 1024 * 2];
133                     // 将接受到的数据存入到输入  arrMsgRec中;
134                     int length = -1;
135                     try
136                     {
137                         length = socketClient.Receive(arrMsgRec); // 接收数据,并返回数据的长度;
138                     }
139                     catch
140                     {
141                         Flag_Receive = false;
142                         // 从通信线程集合中删除被中断连接的通信线程对象;
143                         string keystr = socketClient.RemoteEndPoint.ToString();
144                         dic_ClientSocket.Remove(keystr);//删除客户端字典中该socket
145                         dic_ClientThread[keystr].Abort();//关闭线程
146                         dic_ClientThread.Remove(keystr);//删除字典中该线程
147 
148                         tcpClient = null;
149                         socketClient = null;
150                         break;
151                     }
152                     byte[] buf = new byte[length];
153                     Array.Copy(arrMsgRec, buf, length);
154                     lock (tcpClient.m_Buffer)
155                     {
156                         tcpClient.AddQueue(buf);
157                     }
158                 }
159                 catch
160                 {
161 
162                 }
163                 Thread.Sleep(100);
164             }
165         }
166         /// <summary>
167         /// 发送数据给指定的客户端
168         /// </summary>
169         /// <param name="_endPoint">客户端套接字</param>
170         /// <param name="_buf">发送的数组</param>
171         /// <returns></returns>
172         public bool SendData(string _endPoint, byte[] _buf)
173         {
174             MySession myT = new MySession();
175             if (dic_ClientSocket.TryGetValue(_endPoint, out myT))
176             {
177                 myT.Send(_buf);
178                 return true;
179             }
180             else
181             {
182                 return false;
183             }
184         }
185     }
186 
187     /// <summary>
188     /// 会话端
189     /// </summary>
190     public class MySession
191     {
192         public Socket TcpSocket;//socket对象
193         public List<byte> m_Buffer = new List<byte>();//数据缓存区
194 
195         public MySession()
196         {
197 
198         }
199 
200         /// <summary>
201         /// 发送数据
202         /// </summary>
203         /// <param name="buf"></param>
204         public void Send(byte[] buf)
205         {
206             if (buf != null)
207             {
208                 TcpSocket.Send(buf);
209             }
210         }
211         /// <summary>
212         /// 获取连接的ip
213         /// </summary>
214         /// <returns></returns>
215         public string GetIp()
216         {
217             IPEndPoint clientipe = (IPEndPoint)TcpSocket.RemoteEndPoint;
218             string _ip = clientipe.Address.ToString();
219             return _ip;
220         }
221         /// <summary>
222         /// 关闭连接
223         /// </summary>
224         public void Close()
225         {
226             TcpSocket.Shutdown(SocketShutdown.Both);
227         }
228         /// <summary>
229         /// 提取正确数据包
230         /// </summary>
231         public byte[] GetBuffer(int startIndex, int size)
232         {
233             byte[] buf = new byte[size];
234             m_Buffer.CopyTo(startIndex, buf, 0, size);
235             m_Buffer.RemoveRange(0, startIndex + size);
236             return buf;
237         }
238 
239         /// <summary>
240         /// 添加队列数据
241         /// </summary>
242         /// <param name="buffer"></param>
243         public void AddQueue(byte[] buffer)
244         {
245             m_Buffer.AddRange(buffer);
246         }
247         /// <summary>
248         /// 清除缓存
249         /// </summary>
250         public void ClearQueue()
251         {
252             m_Buffer.Clear();
253         }
254     }
255 }

猜你喜欢

转载自www.cnblogs.com/canwyq/p/10114928.html