C#-关于TcpListener的AcceptTcpClient()方法造成线程阻塞,进而程序无法彻底关闭的问题
|
admin
2021年2月23日 11:18
本文热度 3435
|
在《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 编辑过