不断运行服务器

时间:2011-04-19 10:56:00

标签: c# .net tcp

当客户端断开连接时,服务器将关闭。告诉我如何在第一次会议结束后留下连接新客户的能力。提前谢谢。

namespace tcpserver
{
    class Program
    {
        static void Main(string[] args)
        {
            string cmd;
            int port = 56568;
            Server Serv = new Server(); // Создаем новый экземпляр класса 
            // сервера

            Serv.Create(port);

            while (true)
            {
                cmd = Console.ReadLine(); // Ждем фразы EXIT когда 
                // понадобится выйти из приложения.
                // типа интерактивность.
                if (cmd == "EXIT")
                {
                    Serv.Close(); // раз выход – значит выход. Серв-нах.
                    return;
                }
            }


            //while (Serv.Close() == true) { Serv.Create(port); }
        }

        public class Server // класс сервера.
        {
            private int LocalPort;
            private Thread ServThread; // экземпляр потока
            TcpListener Listener; // листенер))))

            public void Create(int port)
            {
                LocalPort = port;
                ServThread = new Thread(new ThreadStart(ServStart));
                ServThread.Start(); // запустили поток. Стартовая функция – 
                // ServStart, как видно выше
            }

            public void Close() // Закрыть серв?
            {
                Listener.Stop();
                ServThread.Abort();
                return;
            }

            private void ServStart()
            {
                Socket ClientSock; // сокет для обмена данными.
                string data;
                byte[] cldata = new byte[1024]; // буфер данных
                Listener = new TcpListener(LocalPort);
                Listener.Start(); // начали слушать
                Console.WriteLine("Waiting connections on " + Convert.ToString(LocalPort) + " port");
                try
                {
                    ClientSock = Listener.AcceptSocket(); // пробуем принять клиента
                }
                catch
                {
                    ServThread.Abort(); // нет – жаль(
                    return;
                }
                int i = 0;

                if (ClientSock.Connected)
                {
                    while (true)
                    {
                        try
                        {
                            i = ClientSock.Receive(cldata); // попытка чтения 
                            // данных
                        }
                        catch
                        {
                        }

                        try
                        {
                            if (i > 0)
                            {

                                data = Encoding.ASCII.GetString(cldata).Trim();
                                Console.WriteLine("<" + data);
                                if (data == "CLOSE") // если CLOSE – 
                                // вырубимся
                                {
                                    ClientSock.Send(Encoding.ASCII.GetBytes("Closing the server..."));
                                    ClientSock.Close();
                                    Listener.Stop();
                                    Console.WriteLine("Server closed. Reason: client wish! Type EXIT to quit the application.");
                                    ServThread.Abort();
                                    return;
                                }

                                else
                                { // нет – шлем данные взад.
                                    ClientSock.Send(Encoding.ASCII.GetBytes("Your data: " + data));
                                }
                            }
                        }
                        catch
                        {
                            ClientSock.Close(); //
                            Listener.Stop();
                            Console.WriteLine("Client disconnected. Server closed.");
                            ServThread.Abort();
                        }
                    }
                }
            }
        } 
    }
}

2 个答案:

答案 0 :(得分:3)

典型的线程服务器代码将更像这样(在伪代码中,因为我不知道足够的Java细节来准确地写它,并且因为C有点令人窒息):

socket s = new socket
bind s to an optional IP, port
listen s
while true
    cli = accept s
    t = new thread(handle_client, cli)
    maybe disown thread, so no need to join it later
    t.start

重要的一点是,创建套接字,将其绑定到一个地址,listen都在循环外部处理,而accept()和起始线程是内部循环。

您可能希望将整个块包装在另一个线程中;这是可以接受的。重要的是将listenaccept和每个客户thread分开。这允许您的代码停止接受新连接,但处理现有客户端,直到它们断开连接,或在使用分配资源但仍继续接受连接等时断开现有连接。(注意您的上一个catch块将如何终止服务器如果任何单个客户端套接字抛出异常;使用通常的服务器布局很容易避免这种代码。)

答案 1 :(得分:2)

替换

                                ServThread.Abort();                                    
                                return;

使用continue,这不会破坏while循环,但会停止当前的“round”。请考虑阅读:http://www.codeproject.com/KB/IP/serversocket.aspx

构建的好项目