首页 > 学院 > 开发设计 > 正文

C# TCP退出Accept阻塞的两种方法

2019-11-08 18:52:13
字体:
来源:转载
供稿:网友

C# TCP退出Accept阻塞的两种方法

方法一:将侦听套接字强行关掉,这样会使Accept引发异常,从而达到退出阻塞的目的。

方法二:先拆除循环条件,再给监听端口发送一条自定义命令,解析成功后,Accept自然退出阻塞。

后台代码:

using System;using System.Text;using System.Windows;using System.Threading;using System.Net;using System.Net.Sockets;namespace SocketBlockingInterrupt{    public partial class MainWindow : Window    {        bool bIsExecute;        TcpListener listener;//监听套接字        SynchronizationContext synContext;        public MainWindow()        {            InitializeComponent();            synContext = SynchronizationContext.Current;            btnStop.IsEnabled = false;        }        PRivate void btnStart_Click(object sender, RoutedEventArgs e)        {            bIsExecute = true; //建立循环条件            btnStart.IsEnabled = false;            btnStop.IsEnabled = true;            //开启监听线程            Thread t = new Thread(new ThreadStart(ListenThread));            t.IsBackground = true;            t.Start();        }        void ListenThread()        {            ipEndPoint localEP = new IPEndPoint(IPAddress.Any, 9000);            listener = new TcpListener(localEP);            listener.Start();         //启动监听,非阻塞            synContext.Post(updateUI, "监听线程:正在监听中...");            while (bIsExecute) //循环条件            {                byte[] recvBuff = new byte[512];                //捕获异常,强行退出Accept阻塞                try                {                    synContext.Post(updateUI, "监听线程:Accept正在阻塞中...");                    TcpClient client = listener.AcceptTcpClient();     // 等待连接(阻塞)                    synContext.Post(updateUI, "监听线程:收到连接请求,已退出Accept阻塞");                    int recvByte = client.Client.Receive(recvBuff);// 建立连接                    // 解析命令                    byte[] buff = new byte[recvByte];                    for (int i = 0; i < recvByte; i++ ) { buff[i] = recvBuff[i]; }                    string exitByt = Encoding.ASCII.GetString(buff);                    if (exitByt == "Exit")                    {                        synContext.Post(updateUI, "监听线程:收到数据" + exitByt);                        break;                    }                }                catch (SocketException ex)                {                    synContext.Post(updateUI, "监听线程:发生异常,Accept阻塞被强行退出:" + ex.Message);                    break;                }            }            synContext.Post(updateUI, "监听线程:已成功退出监听");        }        private void btnStop_Click(object sender, RoutedEventArgs e)        {            bIsExecute = false; //此处拆除循环条件            //方法1:直接停止监听套接字,引发异常从而强行使Accept退出阻塞。            //---------------------------------------------            //if (listener != null)            //{            //    listener.Stop();            //}            //---------------------------------------------                        //方法2:主动发送一条数据,使Accept自然地退出阻塞。            //---------------------------------------------            TcpClient tcpClient = new TcpClient();            tcpClient.Connect("127.0.0.1",9000);            NetworkStream ns = tcpClient.GetStream();            if (ns.CanWrite)            {                Byte[] sendBytes = Encoding.ASCII.GetBytes("Exit");                ns.Write(sendBytes, 0, sendBytes.Length);                lbMsg.Items.Add("发送退出命令成功!");            }            else            {                lbMsg.Items.Add("发送退出命令失败!");                return;            }            ns.Close();            tcpClient.Close();            //---------------------------------------------            btnStart.IsEnabled = true;            btnStop.IsEnabled = false;        }        void updateUI(object o)        {            string str = (string)o;            lbMsg.Items.Add(str);        }    }}

WPF前台代码:

<Window x:Class="SocketBlockingInterrupt.MainWindow"        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        Title="MainWindow" Height="350" Width="525">    <Grid>        <Button Content="开始侦听" Height="23" HorizontalAlignment="Left" Margin="12,12,0,0" Name="btnStart" VerticalAlignment="Top" Width="75" Click="btnStart_Click" />        <Button Content="结束侦听" Height="23" HorizontalAlignment="Left" Margin="108,12,0,0" Name="btnStop" VerticalAlignment="Top" Width="75" Click="btnStop_Click" />        <ListBox Height="258" HorizontalAlignment="Left" Margin="12,41,0,0" Name="lbMsg" VerticalAlignment="Top" Width="479" />    </Grid></Window>


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表