https://blog.csdn.net/nuistchn/article/details/50809158編程
在《C#高級編程》第7版第24章,有提到使用TCP類。tcp
書中寫了一個實例,兩個winform,其中一個點擊按鈕發送字符串,另外一個winform進行接收。這個實例有個缺點,只能接收一次。ui
我將這個實例進行了改造。初版作好後,能夠進行接收和發送,可是出現一個問題,就是在關閉程序後,在電腦的任務管理器中看到還有進程在跑。spa
進行了一些嘗試後改了第二版,終於解決了這個問題。.net
看一眼這個程序線程
在兩臺電腦上分別運行此程序,注意要設置對方的IP地址。orm
我直接貼上第二版的代碼,而後在標明修改的哪兒。blog
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace TCPSend
{
public partial class Form1 : Form
{
//定義一個委託,用於更新Form1上控件。
protected delegate void UpdateDisplayDelegate(string text);
public Thread thread = null;
public TcpClient tcpClientReceiver = null;
TcpListener tcpListener = null;
public Boolean boolStop = false;
public Form1()
{
InitializeComponent();
thread = new Thread(new ThreadStart(Listen));
thread.Start();
}
public void Listen()
{
string LocalIp = GetSelfIp();
if (LocalIp == null)
{
return;
}
IPAddress localAddr = IPAddress.Parse(LocalIp);
Int32 port = 2112;
tcpListener = new TcpListener(localAddr, port);
tcpClientReceiver = new TcpClient();
tcpListener.Start();
while (true)
{
if (!tcpListener.Pending())
{
//爲了不每次都被tcpListener.AcceptTcpClient()阻塞線程,添加了此判斷,
//no connection requests have arrived。
//當沒有鏈接請求時,什麼也不作,有了請求再執行到tcpListener.AcceptTcpClient()
}
else
{
tcpClientReceiver = tcpListener.AcceptTcpClient();
NetworkStream ns = tcpClientReceiver.GetStream();
StreamReader sr = new StreamReader(ns);
string result = sr.ReadToEnd();
Invoke(new UpdateDisplayDelegate(UpdateDisplay), new object[] { result });
}
if (boolStop)
{
break;
}
}
}
public void UpdateDisplay(string text)
{
string currentContents = textBox4.Text;
currentContents += text+"\r\n"; //必須用"\r\n"在窗口中才能體現出換行
textBox4.Text = currentContents;
}
//send message
private void button1_Click(object sender, EventArgs e)
{
SendMessage();
}
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); //將string類型轉換爲byte[]
for (int i = 0; i < contentBytes.Length; i++)
{
ns.WriteByte(contentBytes[i]);
}
ns.Close();
tcpClient.Close();
textBox3.Text = "";
}
//得到本地的IP地址
public string GetSelfIp()
{
System.Net.IPAddress[] addressList = Dns.GetHostByName(Dns.GetHostName()).AddressList;
if (addressList.Length == 1)
{
return addressList[0].ToString();
}
else
{
MessageBox.Show("當前只支持設置一個IP的電腦,您的電腦設有多個IP地址");
}
return null;
}
//在關閉以前,將boolStop設置爲true,thread既能夠結束了。
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
boolStop = true;
}
}
}進程
相對於初版,主要是添加了變量boolStop,用於控制線程中while循環結束的時機。第二點就是在while循環中增長了一個判斷,if (!tcpListener.Pending()),這樣在對方沒有發送消息時,是不會執行到tcpListener.AcceptTcpClient();的。這樣就不會形成線程的阻塞了。這樣直接關閉了winform,線程thread也會相應的結束。utf-8
不然就會形成以下的狀況,關閉了程序,可是任務管理器中,仍然可以看到進程。
————————————————版權聲明:本文爲CSDN博主「nuistchn」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。原文連接:https://blog.csdn.net/nuistchn/article/details/50809158