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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM