LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

C#-關(guān)于TcpListener的AcceptTcpClient()方法造成線程阻塞,進(jìn)而程序無法徹底關(guān)閉的問題

admin
2021年2月23日 11:18 本文熱度 3722
在《C#高級(jí)編程》第7版第24章,有提到使用TCP類。
書中寫了一個(gè)實(shí)例,兩個(gè)winform,其中一個(gè)點(diǎn)擊按鈕發(fā)送字符串,另一個(gè)winform進(jìn)行接收。這個(gè)實(shí)例有個(gè)缺點(diǎn),只能接收一次。
我將這個(gè)實(shí)例進(jìn)行了改造。第一版做好后,可以進(jìn)行接收和發(fā)送,但是出現(xiàn)一個(gè)問題,就是在關(guān)閉程序后,在電腦的任務(wù)管理器中看到還有進(jìn)程在跑。
進(jìn)行了一些嘗試后改了第二版,終于解決了這個(gè)問題。
看一眼這個(gè)程序:


在兩臺(tái)電腦上分別運(yùn)行此程序,注意要設(shè)置對(duì)方的IP地址。


我直接貼上第二版的代碼,然后在標(biāo)明修改的哪兒。
  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. //定義一個(gè)委托,用于更新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. //當(dāng)沒有連接請(qǐng)求時(shí),什么也不做,有了請(qǐng)求再執(zhí)行到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"在窗口中才能體現(xià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類型轉(zhuǎn)換為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("當(dāng)前只支持設(shè)置一個(gè)IP的電腦,您的電腦設(shè)有多個(gè)IP地址");
  99. }
  100. return null;
  101. }
  102. //在關(guān)閉之前,將boolStop設(shè)置為true,thread既可以結(jié)束了。
  103. private void Form1_FormClosing(object sender, FormClosingEventArgs e)
  104. {
  105. boolStop = true;
  106. }
  107. }
  108. }

相對(duì)于第一版,主要是添加了變量boolStop,用于控制線程中while循環(huán)結(jié)束的時(shí)機(jī)。第二點(diǎn)就是在while循環(huán)中增加了一個(gè)判斷,if (!tcpListener.Pending()),這樣在對(duì)方?jīng)]有發(fā)送消息時(shí),是不會(huì)執(zhí)行到tcpListener.AcceptTcpClient();的。這樣就不會(huì)造成線程的阻塞了。這樣直接關(guān)閉了winform,線程thread也會(huì)相應(yīng)的結(jié)束。

否則就會(huì)造成如下的情況,關(guān)閉了程序,但是任務(wù)管理器中,仍然能夠看到進(jìn)程。

該文章在 2021/2/23 11:18:36 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國(guó)內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲(chǔ)管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

黄频国产免费高清视频,久久不卡精品中文字幕一区,激情五月天AV电影在线观看,欧美国产韩国日本一区二区
亚洲国内偷拍福利 | 三级视频欧美不卡在线观看 | 午夜性开放视频久久…爽 | 最新国产区在线 | 中文字幕乱码免费高清视频 | 日本天码AⅤ片在线电影 |