国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

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>


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 金乡县| 丰县| 临海市| 绥芬河市| 上林县| 谢通门县| 黔西县| 康定县| 郁南县| 丹东市| 建宁县| 定安县| 措勤县| 郸城县| 萨嘎县| 凤庆县| 崇左市| 界首市| 金山区| 历史| 文山县| 屯留县| 榆社县| 乌拉特中旗| 革吉县| 枣阳市| 济南市| 黑山县| 高密市| 荥阳市| 华宁县| 尼勒克县| 盘锦市| 绥滨县| 淮阳县| 娄底市| 定陶县| 青海省| 太谷县| 涡阳县| 桐庐县|