1

我正在创建一个由套接字和线程管理的客户端/服务器应用程序。我想知道如何正确关闭套接字和相关线程。这是我的代码:

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;
        }
    }
}
4

1 回答 1

1

您似乎正在覆盖您对socketand的引用incoming。我假设这些是课堂上的字段。我认为您需要保留这些对象的集合,并在关闭时关闭所有这些对象。

此外,中止线程是一个坏主意,因为您不知道线程在中止时正在执行什么操作。通过设置标志并在循环中检查它来进行正常关闭被认为是一种更好的做法。这可能是您异常的原因。我建议您不要中止线程,而是找到一种适当的方法来关闭所有内容。通过这种方式,您更有可能找到一条没有错误的路径。

我会while (true)while (_isRunning). 将其设置为具有公共值的类上的字段。当您关闭时,将其设置为 false 并且线程将正常退出。

于 2012-12-30T18:54:40.690 回答