取消阻止AcceptTcpClient电话 [英] Cancel blocking AcceptTcpClient call

查看:613
本文介绍了取消阻止AcceptTcpClient电话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于大家可能已经知道,接受在C#中传入的TCP连接的最简单方法是通过遍历TcpListener.AcceptTcpClient()。此外,直到获得一个连接这种方式将阻止代码执行。这是非常限制到一个图形用户界面,所以我想监听在任何一个单独的线程或任务的连接。

As everyone may already know, the simplest way to accept incoming TCP connections in C# is by looping over TcpListener.AcceptTcpClient(). Additionally this way will block code execution until a connection is obtained. This is extremely limiting to a GUI, so I want to listen for connections in either a seperate thread or task.

有人告诉我,那线程有几个缺点,但是没有人解释说我这是什么意思。因此,而不是使用线程,我用任务。这个伟大的工程,但是因为AcceptTcpClient方法阻止执行,我找不到处理一个任务取消任何方式。

I have been told, that threads have several disadvantages, however nobody explained me what these are. So instead of using threads, I used tasks. This works great, however since the AcceptTcpClient method is blocking execution, I can't find any way of handling a task cancellation.

目前的代码看起来是这样,但我。不知道我怎么会要取消的任务时,我想程序停止侦听连接

Currently the code looks like this, but I have no idea how I would want to cancel the task when I want the program to stop listening for connections.

首先在任务执行的功能:

First off the function executed in the task:

static void Listen () {
// Create listener object
TcpListener serverSocket = new TcpListener ( serverAddr, serverPort );

// Begin listening for connections
while ( true ) {
    try {
        serverSocket.Start ();
    } catch ( SocketException ) {
        MessageBox.Show ( "Another server is currently listening at port " + serverPort );
    }

    // Block and wait for incoming connection
    if ( serverSocket.Pending() ) {
        TcpClient serverClient = serverSocket.AcceptTcpClient ();
        // Retrieve data from network stream
        NetworkStream serverStream = serverClient.GetStream ();
        serverStream.Read ( data, 0, data.Length );
        string serverMsg = ascii.GetString ( data );
        MessageBox.Show ( "Message recieved: " + serverMsg );

        // Close stream and TcpClient connection
        serverClient.Close ();
        serverStream.Close ();

        // Empty buffer
        data = new Byte[256];
        serverMsg = null;
    }
}



二,启动和停止监听服务的功能:

Second, the functions starting and stopping the listening service:

private void btnListen_Click (object sender, EventArgs e) {
    btnListen.Enabled = false;
    btnStop.Enabled = true;
    Task listenTask = new Task ( Listen );
    listenTask.Start();
}

private void btnStop_Click ( object sender, EventArgs e ) {
    btnListen.Enabled = true;
    btnStop.Enabled = false;
    //listenTask.Abort();
}



我只是需要一些更换listenTask.Abort()调用(我注释掉因为该方法不存在)

I just need something to replace the listenTask.Abort() call (Which I commented out because the method doesn't exist)

推荐答案

下面的代码将关闭/中止AcceptTcpClient时isRunning变量为假

The following code will close/abort AcceptTcpClient when isRunning variable becomes false

public static bool isRunning;

delegate void mThread(ref book isRunning);
delegate void AccptTcpClnt(ref TcpClient client, TcpListener listener);

public static main()
{
   isRunning = true;
   mThread t = new mThread(StartListening);
   Thread masterThread = new Thread(() => t(this, ref isRunning));
   masterThread.IsBackground = true; //better to run it as a background thread
   masterThread.Start();
}

public static void AccptClnt(ref TcpClient client, TcpListener listener)
{
  if(client == null)
    client = listener.AcceptTcpClient(); 
}

public static void StartListening(ref bool isRunning)
{
  TcpListener listener = new TcpListener(new IPEndPoint(IPAddress.Any, portNum));

  try
  {
     listener.Start();

     TcpClient handler = null;
     while (isRunning)
     {
        AccptTcpClnt t = new AccptTcpClnt(AccptClnt);

        Thread tt = new Thread(() => t(ref handler, listener));
        tt.IsBackground = true;
        tt.Start(); //the AcceptTcpClient() is a blocking method, so we are invoking it    in a seperate thread so that we can break the while loop wher isRunning becomes false

        while (isRunning && tt.IsAlive && handler == null) 
        Thread.Sleep(500); //change the time as you prefer


        if (handler != null)
        {
           //handle the accepted connection here
        }        
        else if (!isRunning && tt.IsAlive)
        {
           tt.Abort();
        }                   
   }
   listener.Stop();         
}
catch (Exception e)
{
   Console.WriteLine(e.ToString());
}

}

这篇关于取消阻止AcceptTcpClient电话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆