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> 该文章在 2021/2/23 11:33:58 编辑过 |
关键字查询
相关文章
正在查询... |