select是一种比较古老但一直被证明性能很好的socket模式,它可以让你以消息驱动的模式书写socket程序。网上C++的例子很多,但C#的例子极少。
上代码:
namespace Server { class Program { // Thread signal. public static ManualResetEvent allDone = new ManualResetEvent(false); private static Socket handler = null; private static ArrayList g_CliSocketArr = new ArrayList(); private static Object thisLock = new Object(); public Program() { } public static void StartListening() { // Data buffer for incoming data. byte[] bytes = new Byte[1024]; IPAddress ipAddress = IPAddress.Parse("192.168.1.71");// IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000); // Create a TCP/IP socket. Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp ); // Bind the socket to the local endpoint and listen for incoming connections. try { listener.Bind(localEndPoint); listener.Listen(100); // Start an asynchronous socket to listen for connections. Console.WriteLine("Waiting for a connection..."); Thread worker = new Thread(new ThreadStart(WorkerThread));//创建一个线程用于处理请求 worker.Start(); while (true) { Socket sClient = listener.Accept(); Console.WriteLine("There is a new connection."); g_CliSocketArr.Add(sClient); } } catch (Exception e) { Console.WriteLine(e.ToString()); } Console.WriteLine("\nPress ENTER to continue..."); Console.Read(); } public static void WorkerThread() { Socket socket1 = null; ArrayList readList = new ArrayList(); // readList.Add(socket0); while (true) { lock (thisLock) { readList.Clear(); for (int i = 0; i < g_CliSocketArr.Count; i++) { readList.Add(g_CliSocketArr[i]); } } if (readList.Count <= 0) { Thread.Sleep(100); continue; } try { Socket.Select(readList, null, null, 500); for (int i = 0; i < readList.Count; i++) { socket1 = (Socket)readList[i]; Console.WriteLine("There is a new message from client."); byte[] buffer = new byte[1024]; int recLen = socket1.Receive(buffer); if(recLen > 0) { // recLen = socket1.Receive(buffer); } else {//如果返回0,表示客户端已经断开连接,须将此socket关闭然后从连接池中清除 Console.WriteLine("Rece 0 length."); for (int ii = 0; ii < g_CliSocketArr.Count; ii++) { Socket s = (Socket)g_CliSocketArr[ii]; if (s == socket1) g_CliSocketArr.RemoveAt(ii); } socket1.Shutdown(SocketShutdown.Both); socket1.Close(); break; } socket1.Send(buffer,recLen, SocketFlags.None); } } catch (SocketException e) { Console.WriteLine("{0} Error code: {1}.", e.Message, e.ErrorCode); for (int ii = 0; ii < g_CliSocketArr.Count; ii++) { Socket s = (Socket)g_CliSocketArr[ii]; if (s == socket1) g_CliSocketArr.RemoveAt(ii); } socket1.Shutdown(SocketShutdown.Both); socket1.Close(); } } } static void Main(string[] args) { StartListening(); } } }
C#下用select方法实现socket服务端
时间: 2024-10-12 13:35:27