GJM : 中断被Socket.Accept阻塞的线程

原帖地址:http://blog.csdn.net/kingfox/article/details/7233350

原文作者:狐帝

刚刚学习C#,在编写一个网络通讯的程序的时候,遇到了点麻烦。监听代码是放在一个线程中,当在线程中调用Socket.Accept()函数时,倘若这时需要中止该线程,C#似乎没有提供现成的办法,使用了Thread.Abort()和Thread.Interrupt()函数,都没有用。有人说用异步Accept方法避免阻塞,可是用这种方法就得在线程中不停地轮询Socket的状态,会导致CPU负荷增加。还有人提出可以现在程序内部创建一个对侦听Socket的连接,然后发送特定的推出数据序列,当监听程序收到这个特殊序列后就主动结束线程。这个方法虽然可以解决问题,但是未免复杂了些。

想来想去,突然想到如果将监听socket关闭掉,引发socket异常,然后在监听线程中捕获这个异常不就可以中止监听线程了吗,试验了一下,果然可以。监听线程的代码如下:

[csharp] view plain copy
 
  1. using System;  
  2. using System.IO;  
  3. using System.Net.Sockets;  
  4. using System.Net;  
  5.   
  6. public class ListenThread  
  7. {  
  8.    public void run()  
  9.    {  
  10.       Console.Write("creating listen socket ...");  
  11.       listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);  
  12.       listenSocket.Bind(new IPEndPoint(IPAddress.Any, 65365));  
  13.       listenSocket.Listen(0);  
  14.       Console.Write("    done. ");  
  15.   
  16.       try  
  17.       {  
  18.          Console.Write("listening ...");  
  19.          ioSocket = listenSocket.Accept();  
  20.          Console.Write("    accepted. ");  
  21.   
  22.          Console.Write("creating I/O thread ...");  
  23.          // new Thread(new ThreadStart(this.networkIOThreadProc)).Start();  
  24.          Console.Write("    done. ");  
  25.       }  
  26.       catch (Exception e)  
  27.       {  
  28.          Console.WriteLine("Thread aborted.");  
  29.       }  
  30.       finally  
  31.       {  
  32.          Console.WriteLine("Thread resource released.");  
  33.       }  
  34.    }  
  35.   
  36.    public void stop()  
  37.    {  
  38.       if (listenSocket != null)  
  39.       {  
  40.          listenSocket.Close();  
  41.       }  
  42.    }  
  43.   
  44.    private Socket listenSocket = null;  
  45.    private Socket ioSocket = null;  
  46.   
  47. }  


创建线程的代码如下:

[csharp] view plain copy
 
  1. ListenThread listener = new ListenThread();  
  2. Thread listenThread = new Thread(new ThreadStart(listener.run));  
  3. listenThread.Start();  


中止线程的代码如下:

[csharp] view plain copy
 
  1. listener.stop();  


调用线程类的stop函数之后,会将处于监听远程连接的listenSocket关闭掉,这时会导致引发System.Net.Sockets.SocketException,在线程代码中捕获并处理这个异常就行了。这种方法实现简单,也不会产生额外的CPU资源。

原文地址:https://www.cnblogs.com/TDou/p/6122743.html