Постоянно работающий сервер - PullRequest
1 голос
/ 19 апреля 2011

Когда клиент отключается, сервер закрывается. Подскажите, как оставить возможность подключать новых клиентов после закрытия первой сессии. Заранее спасибо.

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 ]

3 голосов
/ 19 апреля 2011

Типичный многопоточный серверный код будет выглядеть примерно так (в псевдокоде, потому что я не знаю достаточно деталей 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() и начальные потоки внутри цикла.

Возможно, вы захотите обернуть весь этот блок в другой поток;это приемлемо.Важной частью является отделение listen от accept и для каждого клиента thread.Это позволяет вашему коду перестать принимать новые подключения, но обрабатывать существующих клиентов до тех пор, пока они не отключатся, или отключить существующие подключения, когда они используют выделенные им ресурсы, но продолжают принимать подключения и т. Д. (Обратите внимание, как ваш последний блок catch завершит работу сервера, если таковой имеется).один клиентский сокет вызывает исключение, такого кода легко избежать при обычной компоновке сервера.)

2 голосов
/ 19 апреля 2011

замените

                                ServThread.Abort();                                    
                                return;

вместо продолжения, это не разорвет цикл while и остановит текущий «раунд».Пожалуйста, подумайте: http://www.codeproject.com/KB/IP/serversocket.aspx хороший проект для сборки из

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...