C# TCP退出Accept阻塞的兩種方法
當(dāng)前位置:點晴教程→知識管理交流
→『 技術(shù)文檔交流 』
方法一:將偵聽套接字強行關(guān)掉,這樣會使Accept引發(fā)異常,從而達(dá)到退出阻塞的目的。 方法二:先拆除循環(huán)條件,再給監(jiān)聽端口發(fā)送一條自定義命令,解析成功后,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;//監(jiān)聽套接字 SynchronizationContext
synContext; public MainWindow() { InitializeComponent(); synContext =
SynchronizationContext.Current; btnStop.IsEnabled = false; } private void btnStart_Click(object sender, RoutedEventArgs e) { bIsExecute = true; //建立循環(huán)條件 btnStart.IsEnabled = false; btnStop.IsEnabled = true; //開啟監(jiān)聽線程 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(); //啟動監(jiān)聽,非阻塞 synContext.Post(updateUI, "監(jiān)聽線程:正在監(jiān)聽中..."); while (bIsExecute) //循環(huán)條件 { byte[] recvBuff = new byte[512]; //捕獲異常,強行退出Accept阻塞 try { synContext.Post(updateUI, "監(jiān)聽線程:Accept正在阻塞中..."); TcpClient client
= listener.AcceptTcpClient(); // 等待連接(阻塞) synContext.Post(updateUI, "監(jiān)聽線程:收到連接請求,已退出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,
"監(jiān)聽線程:收到數(shù)據(jù)" + exitByt); break; } } catch (SocketException ex) {
synContext.Post(updateUI, "監(jiān)聽線程:發(fā)生異常,Accept阻塞被強行退出:" + ex.Message); break; } }
synContext.Post(updateUI, "監(jiān)聽線程:已成功退出監(jiān)聽"); } private void btnStop_Click(object sender, RoutedEventArgs e) { bIsExecute = false; //此處拆除循環(huán)條件 //方法1:直接停止監(jiān)聽套接字,引發(fā)異常從而強行使Accept退出阻塞。 //--------------------------------------------- //if (listener != null) //{ //
listener.Stop(); //} //--------------------------------------------- //方法2:主動發(fā)送一條數(shù)據(jù),使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("發(fā)送退出命令成功!"); } else { lbMsg.Items.Add("發(fā)送退出命令失??!"); 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="結(jié)束偵聽" 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> 該文章在 2021/2/23 11:33:58 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |