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资源。

  • 相关阅读:
    百度面试题:把数组排成最小的数
    面试题:在O(1)时间删除链表结点
    从第一字符串中删除第二个字符串中所有的字符
    在一个字符串中找到第一个只出现一次的字符
    大整数运算
    输出1到最大的N位数
    删除字符串中的数字并压缩字符串
    排列 或组合问题的解法(包含回溯法)
    卡特兰数(Catalan)简介
    编程之美-分层遍历二叉树
  • 原文地址:https://www.cnblogs.com/TDou/p/6122743.html
Copyright © 2011-2022 走看看