zoukankan      html  css  js  c++  java
  • 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资源。

  • 相关阅读:
    Java实现 LeetCode 792 自定义字符串排序(暴力)
    Java实现 LeetCode 792 自定义字符串排序(暴力)
    asp.net session对象的持久化
    Java实现 LeetCode 791 自定义字符串排序(桶排序)
    Java实现 LeetCode 791 自定义字符串排序(桶排序)
    Java实现 LeetCode 791 自定义字符串排序(桶排序)
    Java实现 LeetCode 790 多米诺和托米诺平铺(递推)
    Java实现 LeetCode 790 多米诺和托米诺平铺(递推)
    Java实现 LeetCode 790 多米诺和托米诺平铺(递推)
    小白也能看懂的约瑟夫环问题
  • 原文地址:https://www.cnblogs.com/TDou/p/6122743.html
Copyright © 2011-2022 走看看