LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

C#-关于TcpListener的AcceptTcpClient()方法造成线程阻塞,进而程序无法彻底关闭的问题

admin
2021年2月23日 11:18 本文热度 3250
在《C#高级编程》第7版第24章,有提到使用TCP类。
书中写了一个实例,两个winform,其中一个点击按钮发送字符串,另一个winform进行接收。这个实例有个缺点,只能接收一次。
我将这个实例进行了改造。第一版做好后,可以进行接收和发送,但是出现一个问题,就是在关闭程序后,在电脑的任务管理器中看到还有进程在跑。
进行了一些尝试后改了第二版,终于解决了这个问题。
看一眼这个程序:


在两台电脑上分别运行此程序,注意要设置对方的IP地址。


我直接贴上第二版的代码,然后在标明修改的哪儿。
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9. using System.IO;
  10. using System.Net;
  11. using System.Net.Sockets;
  12. using System.Threading;
  13. namespace TCPSend
  14. {
  15. public partial class Form1 : Form
  16. {
  17. //定义一个委托,用于更新Form1上控件。
  18. protected delegate void UpdateDisplayDelegate(string text);
  19. public Thread thread = null;
  20. public TcpClient tcpClientReceiver = null;
  21. TcpListener tcpListener = null;
  22. public Boolean boolStop = false;
  23. public Form1()
  24. {
  25. InitializeComponent();
  26. thread = new Thread(new ThreadStart(Listen));
  27. thread.Start();
  28. }
  29. public void Listen()
  30. {
  31. string LocalIp = GetSelfIp();
  32. if (LocalIp == null)
  33. {
  34. return;
  35. }
  36. IPAddress localAddr = IPAddress.Parse(LocalIp);
  37. Int32 port = 2112;
  38. tcpListener = new TcpListener(localAddr, port);
  39. tcpClientReceiver = new TcpClient();
  40. tcpListener.Start();
  41. while (true)
  42. {
  43. if (!tcpListener.Pending())
  44. {
  45. //为了避免每次都被tcpListener.AcceptTcpClient()阻塞线程,添加了此判断,
  46. //no connection requests have arrived。
  47. //当没有连接请求时,什么也不做,有了请求再执行到tcpListener.AcceptTcpClient()
  48. }
  49. else
  50. {
  51. tcpClientReceiver = tcpListener.AcceptTcpClient();
  52. NetworkStream ns = tcpClientReceiver.GetStream();
  53. StreamReader sr = new StreamReader(ns);
  54. string result = sr.ReadToEnd();
  55. Invoke(new UpdateDisplayDelegate(UpdateDisplay), new object[] { result });
  56. }
  57. if (boolStop)
  58. {
  59. break;
  60. }
  61. }
  62. }
  63. public void UpdateDisplay(string text)
  64. {
  65. string currentContents = textBox4.Text;
  66. currentContents += text+"\r\n"; //必须用"\r\n"在窗口中才能体现出换行
  67. textBox4.Text = currentContents;
  68. }
  69. //send message
  70. private void button1_Click(object sender, EventArgs e)
  71. {
  72. SendMessage();
  73. }
  74. public void SendMessage()
  75. {
  76. TcpClient tcpClient = new TcpClient(textBox1.Text, Int32.Parse(textBox2.Text));
  77. NetworkStream ns = tcpClient.GetStream();
  78. string message = textBox3.Text;
  79. byte[] contentBytes = Encoding.GetEncoding("utf-8").GetBytes(message); //将string类型转换为byte[]
  80. for (int i = 0; i < contentBytes.Length; i++)
  81. {
  82. ns.WriteByte(contentBytes[i]);
  83. }
  84. ns.Close();
  85. tcpClient.Close();
  86. textBox3.Text = "";
  87. }
  88. //获得本地的IP地址
  89. public string GetSelfIp()
  90. {
  91. System.Net.IPAddress[] addressList = Dns.GetHostByName(Dns.GetHostName()).AddressList;
  92. if (addressList.Length == 1)
  93. {
  94. return addressList[0].ToString();
  95. }
  96. else
  97. {
  98. MessageBox.Show("当前只支持设置一个IP的电脑,您的电脑设有多个IP地址");
  99. }
  100. return null;
  101. }
  102. //在关闭之前,将boolStop设置为true,thread既可以结束了。
  103. private void Form1_FormClosing(object sender, FormClosingEventArgs e)
  104. {
  105. boolStop = true;
  106. }
  107. }
  108. }

相对于第一版,主要是添加了变量boolStop,用于控制线程中while循环结束的时机。第二点就是在while循环中增加了一个判断,if (!tcpListener.Pending()),这样在对方没有发送消息时,是不会执行到tcpListener.AcceptTcpClient();的。这样就不会造成线程的阻塞了。这样直接关闭了winform,线程thread也会相应的结束。

否则就会造成如下的情况,关闭了程序,但是任务管理器中,仍然能够看到进程。

该文章在 2021/2/23 11:18:36 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved