我正在创建一个由套接字和线程管理的客户端/服务器应用程序。 我想知道如何正确关闭套接字和相关的线程。 这是我的代码:
protected override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
try
{
if (UserList.Count > 0)
{
foreach (User user in UserList)
{
Socket socketUser = user.getSocket();
socketUser.Send(Encoding.ASCII.GetBytes("!close"));
socketUser.Close();
}
}
thrAccept.Abort();
thrReceive.Abort();
socket.Close();
incoming.Close();
Application.Exit();
}
catch
{
MessageBox.Show("aasa");
}
}
private void connectBtn_Click(object sender, EventArgs e)
{
string port=portNum.Text;
string welcome = "Server up and running - " + System.DateTime.Now.GetDateTimeFormats()[0] + " " + DateTime.Now.ToString("HH:mm") + "\n" + "Listening Port: " + port + "\n";
socket.Bind(new IPEndPoint(IPAddress.Any, Convert.ToInt32(portNum.Text)));
socket.Listen(3);
thrAccept = new Thread(new ThreadStart(Accept));
serverLog.AppendText(welcome + "\n");
thrAccept.Start();
connectBtn.Enabled = false;
}
private void Accept()
{
while (true)
{
incoming = socket.Accept();
thrReceive = new Thread(new ThreadStart(Receive));
thrReceive.Start();
}
}
private void Receive()
{
User user = new User();//create an istance for the class User
while (true)
{
byte[] buffer = new byte[64];
incoming.Receive(buffer);
// the program continue....
如何正确关闭套接字?
班级用户
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
namespace HW2_SERVER
{
class User
{
public string username;
public Socket S;
public string role;
public bool managed;
public User()
{
username = "";
S = null;
role = "";
managed = false;
}
public void setManage(bool i)
{
managed = i;
}
public void setUsername(string u)
{
username = u;
}
public void setSocket(Socket sock)
{
S = sock;
}
public void setRole(string r)
{
role = r;
}
public bool getManaged()
{
return managed;
}
public string getUsername()
{
return username;
}
public Socket getSocket()
{
return S;
}
public string getRole()
{
return role;
}
}
}
答案 0 :(得分:1)
您似乎覆盖了对socket
和incoming
的引用。我假设这些是课堂上的字段。我认为您需要保留这些对象的集合,并在关闭时关闭所有这些对象。
此外,中止线程是一个坏主意,因为您不知道线程在中止时正在执行什么操作。通过设置标志并在循环中检查它来进行正常关闭被认为是更好的做法。这可能是您例外的原因。我建议你不要中止线程,而是找到一个合适的方法来关闭所有东西。你更有可能以这种方式找到无错误的路径。
我会用while (true)
替换你的while (_isRunning)
个循环。将其设置为具有公共值的类上的字段。关闭时,将其设置为false,线程将正常退出。