之前写的一个tcp协议的聊天室,每次点击窗口的*关闭程序后,再次开启该程序出现端口被占用的情况,仔细检查源码后才发现原来C#中如果用winform编程的话主线程关闭时如果没有显式的关闭子线程,子线程会继续运行
以下是源码
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.Net.Sockets;
using System.Threading;
using System.Text.RegularExpressions;
using System.IO;
using System.Collections;
namespace ChatServer
{
public partial class Form1 : Form
{
public Hashtable ht = new Hashtable();
private Thread tcplistenerthread;
private Thread messagethread;
private TcpListener tl;
public Form1()
{
InitializeComponent();
}
private void start_Click(object sender, EventArgs e)
{
//this.richTextBox1.Text += new JavaService.SayHelloPortTypeClient().example("中国");
this.start.Enabled=false;
tl = new TcpListener(int.Parse(this.textBox1.Text));
tl.Start();
tcplistenerthread = new Thread(new ParameterizedThreadStart(Listen));
tcplistenerthread.Start(tl);
}
private void Listen(object tlistener)
{
TcpListener tl = (TcpListener)tlistener;
tl.Start();
while (true)
{
TcpClient tc = tl.AcceptTcpClient();
this.richTextBox1.Text += "\n接收到新的客户端链接:" + tc.Client.RemoteEndPoint;
messagethread = new Thread(new ParameterizedThreadStart(MessageThread));
messagethread.Start(tc);
}
}
private void MessageThread(object j)
{
TcpClient tc=(TcpClient)j;
string key = tc.Client.RemoteEndPoint.ToString();
this.listBox1.Items.Add(key);
this.listBox1.Refresh();
NetworkStream ns = tc.GetStream();
StreamWriter sw = new StreamWriter(ns);
StreamReader sr = new StreamReader(ns);
ht.Add(key,sw);
try
{
while (true)
{
string ss=sr.ReadLine();
this.richTextBox1.Text += "\n"+ss;
this.richTextBox1.Refresh();
}
}
catch (Exception e)
{
ht.Remove(key);
this.listBox1.Items.Remove(key);
this.listBox1.Refresh();
this.richTextBox1.Text += "\n客户端"+key+"断开连接了";
this.richTextBox1.Refresh();
}
}
private void sender_Click(object sender, EventArgs e)
{
ListBox.SelectedObjectCollection lb = this.listBox1.SelectedItems;
string text = this.textBox2.Text;
foreach (string so in lb)
{
StreamWriter sw = (StreamWriter)ht[so];
sw.WriteLine(text);
sw.Flush();
this.richTextBox1.Text += "\n" + so + ":" + text;
this.richTextBox1.Refresh();
}
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
改进后增加了一个关闭事件
private void Form1_FormClosed(object sender, EventArgs e)
{
//Thread.Sleep(2000);
this.richTextBox1.Text += "测帅";
if(messagethread!=null)
messagethread.Abort();
if(tcplistenerthread!=null)
tcplistenerthread.Abort();
if (tl != null)
{
tl.Stop();
tl = null;
}
}
}
并且在form的初始化方法中增加事件监听控制器:
this.FormClosed+=new FormClosedEventHandler(Form1_FormClosed);
测试后发现问题已解决