服务器正在运行。我既不能停止它,也无法将客户端连接到它

时间:2019-07-11 14:44:39

标签: c# tcp client-server

我的服务器应用程序具有以下源代码:

public class ServerClass
{
    private TcpListener listener;
    private List<ClientClass> clientProxyList;
    private int clientCount = -99;
    public string IpAddress { get; set; }
    public int PortNo { get; set; }
    private bool is_started;

    private Thread clientPollingThread;

    public ServerClass()
    {
        clientProxyList = new List<ClientClass>();
        clientCount = 0;
        is_started = false;
    }

    public ServerClass(string ipAddress, int portNo)
    {
        IpAddress = ipAddress;
        PortNo = portNo;

        clientProxyList = new List<ClientClass>();
        clientCount = 0;
        is_started = false;
    }

    private void PollForSingleClients()
    {
        while (listener.Server.Connected)
        {
            string str = clientProxyList[0].Read();
            Console.WriteLine("client  says: " + str);
        }
    }

    private void PollForMultipleClients()
    {
        while (listener.Server.Connected)
        {
            ClientProxy item = new ClientProxy(listener);
            clientProxyList.Add(item);

            while (listener.Server.Connected)
            {
                foreach (ClientClass cc in clientProxyList)
                {
                    string str = cc.Read();
                    Console.WriteLine("client  says: " + str);
                }
            }
        }
    }

    public void StartForSingleClient()
    {
        is_started = true;

        IPAddress ip = IPAddress.Parse(IpAddress);
        listener = new TcpListener(ip, PortNo);

        listener.Start();

        ClientProxy item = new ClientProxy(listener);
        clientProxyList.Add(item);

        //seperate thread is needed because of 2 reasons:
        // 1. if the server craches, the main thread is not closed.
        // 2. the function deosn't return until the while loop ends.
        clientPollingThread = new Thread(delegate ()
        {
            PollForSingleClients();
        });
        clientPollingThread.Start();
    }

    public void StartForMultipleClient()
    {
        is_started = true;

        IPAddress ip = IPAddress.Parse(IpAddress);
        listener = new TcpListener(ip, PortNo);

        listener.Start();

        //seperate thread is needed because of 2 reasons:
        // 1. if the server craches, the main thread is not closed.
        // 2. the function deosn't return until the while loop ends.
        clientPollingThread = new Thread(delegate ()
        {
            PollForMultipleClients();
        });
        clientPollingThread.Start();
    }

    public void Stop()
    {
        foreach (ClientClass cc in clientProxyList)
        {
            cc.Disconnect();
        }

        clientProxyList.Clear();

        listener.Stop();
        listener = null;

        is_started = false;
    }

    public bool IsActive()
    {
        if (is_started == false)
        {
            return false;
        }
        if (listener == null)
        {
            return false;
        }
        if (listener.Server == null)
        {
            return false;
        }

        return true;
    }
}

此代码给我带来的麻烦是,一旦通过调用StartForSingleClient()启动服务器,它就不会停止(因为在下面的代码中,ClientClass.IsServerActive()总是返回 { {1}} )。

我既无法在任务管理器中看到它,也无法启动新服务器,也无法将客户端连接到已经运行的 ghost 服务器。

如何摆脱这个问题?


相关源代码

  

ClientClass.cs

true
  

ClientProxy.cs

public class ClientClass
{
    public string Host { get; set; }
    public int Port { get; set; }

    public TcpClient Tcp { get; protected set; }
    protected BinaryReader reader;
    protected BinaryWriter writer;

    /// <summary>
    /// Creates a clienbt at the Client-end. 
    /// This requires Host and Post property to be set.
    /// </summary>
    public ClientClass()
    {            
    }

    /// <summary>
    /// Creates a client at the Client-end.
    /// </summary>
    /// <param name="host"></param>
    /// <param name="port"></param>
    public ClientClass(string host, int port)
    {
        Host = host;
        Port = port;
    }

    /// <summary>
    /// Connects the client to the server.
    /// </summary>
    /// <returns></returns>
    public bool Connect()
    {
        bool is_connected = IsConnected();

        if (is_connected)
        {
            return true;
        }

        if (!is_connected)
        {
            try
            {
                Tcp = new TcpClient(Host, Port);

                NetworkStream stream = Tcp.GetStream();
                reader = new BinaryReader(stream);
                writer = new BinaryWriter(stream);

                return true;
            }
            catch
            {
                return false;
            }
        }            

        return false;
    }

    public bool IsConnected()
    {
        if (Tcp == null)
        {
            return false;
        }
        else
        {
            Socket s = Tcp.Client;

            bool part1 = s.Poll(1000, SelectMode.SelectRead);
            bool part2 = (s.Available == 0);
            if ((part1 && part2) || !s.Connected)
                return false;
            else
                return true;
        }
    }

    public void Write(string str)
    {
        if (IsConnected())
        {
            byte[] strBytes = Encoding.UTF8.GetBytes(str);
            byte[] lenBytes = BitConverter.GetBytes(strBytes.Length);
            Array.Reverse(lenBytes);
            writer.Write(lenBytes);
            writer.Write(strBytes);
            writer.Flush();
        }
        else
        {
            throw new Exception("Client  is not connected!");
        }
    }

    public string Read()
    {
        if (IsConnected())
        {
            byte[] lenBytes = reader.ReadBytes(4);
            Array.Reverse(lenBytes);
            int len = BitConverter.ToInt32(lenBytes, 0);
            byte[] bytes = reader.ReadBytes(len);
            string str = Encoding.UTF8.GetString(bytes);

            return str;
        }
        else
        {
            throw new Exception("Client  is not connected!");
        }
    } 

    public bool Disconnect()
    {
        if (IsConnected())
        {
            if (Tcp != null)
            {
                Tcp.Close();
                Tcp = null;

                return true;
            }
        }

        return false;
    }

    public bool IsServerActive()
    {
        bool returns = false;

        try
        {
            Connect();

            returns = true;
        }
        catch
        {

        }

        Disconnect();

        return returns;
    }
}

0 个答案:

没有答案