C#-关于TcpListener的AcceptTcpClient()方法造成线程阻塞,进而程序无法彻底关闭的问题
				
									
					
					
						|  | 
							admin 2021年2月23日 11:18
								本文热度 5251 | 
					
				 
				在《C#高级编程》第7版第24章,有提到使用TCP类。
书中写了一个实例,两个winform,其中一个点击按钮发送字符串,另一个winform进行接收。这个实例有个缺点,只能接收一次。
我将这个实例进行了改造。第一版做好后,可以进行接收和发送,但是出现一个问题,就是在关闭程序后,在电脑的任务管理器中看到还有进程在跑。
进行了一些尝试后改了第二版,终于解决了这个问题。
看一眼这个程序:
在两台电脑上分别运行此程序,注意要设置对方的IP地址。
我直接贴上第二版的代码,然后在标明修改的哪儿。
- using System.Collections.Generic; 
- using System.ComponentModel; 
- using System.Windows.Forms; 
- using System.Net.Sockets; 
-     public partial class Form1 : Form 
-         protected delegate void UpdateDisplayDelegate(string text); 
-         public Thread thread = null; 
-         public TcpClient tcpClientReceiver = null; 
-         TcpListener tcpListener = null; 
-         public Boolean boolStop = false; 
-             thread = new Thread(new ThreadStart(Listen)); 
-             string LocalIp = GetSelfIp(); 
-             IPAddress localAddr = IPAddress.Parse(LocalIp); 
-             tcpListener = new TcpListener(localAddr, port); 
-             tcpClientReceiver = new TcpClient(); 
-                 if (!tcpListener.Pending())  
-                    tcpClientReceiver = tcpListener.AcceptTcpClient(); 
-                    NetworkStream ns = tcpClientReceiver.GetStream(); 
-                    StreamReader sr = new StreamReader(ns); 
-                    string result = sr.ReadToEnd();      
-                    Invoke(new UpdateDisplayDelegate(UpdateDisplay), new object[] { result }); 
-         public void UpdateDisplay(string text) 
-             string currentContents = textBox4.Text; 
-             currentContents += text+"\r\n";    
-             textBox4.Text = currentContents; 
-         private void button1_Click(object sender, EventArgs e) 
-         public void SendMessage() 
-             TcpClient tcpClient = new TcpClient(textBox1.Text, Int32.Parse(textBox2.Text)); 
-             NetworkStream ns = tcpClient.GetStream(); 
-             string message = textBox3.Text; 
-             byte[] contentBytes = Encoding.GetEncoding("utf-8").GetBytes(message);  
-             for (int i = 0; i < contentBytes.Length; i++) 
-                 ns.WriteByte(contentBytes[i]); 
-         public string GetSelfIp() 
-             System.Net.IPAddress[] addressList = Dns.GetHostByName(Dns.GetHostName()).AddressList; 
-             if (addressList.Length == 1) 
-                 return addressList[0].ToString();  
-                 MessageBox.Show("当前只支持设置一个IP的电脑,您的电脑设有多个IP地址"); 
-         private void Form1_FormClosing(object sender, FormClosingEventArgs e) 
相对于第一版,主要是添加了变量boolStop,用于控制线程中while循环结束的时机。第二点就是在while循环中增加了一个判断,if (!tcpListener.Pending()),这样在对方没有发送消息时,是不会执行到tcpListener.AcceptTcpClient();的。这样就不会造成线程的阻塞了。这样直接关闭了winform,线程thread也会相应的结束。
否则就会造成如下的情况,关闭了程序,但是任务管理器中,仍然能够看到进程。
该文章在 2021/2/23 11:18:36 编辑过