| 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 编辑过 | 关键字查询 相关文章 正在查询... |