Ummka
Ummka

Reputation: 13

Constantly running server

When a client disconnects, the server closes. Tell me how to leave the ability to connect new customers after the close of the first session .Thanks in advance.

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();
                        }
                    }
                }
            }
        } 
    }
}

Upvotes: 1

Views: 485

Answers (2)

sarnold
sarnold

Reputation: 104080

Typical threaded server code will read more like this (in a pseudo code, because I don't know enough Java details to write it exactly, and because C is a bit stifling):

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

The important point is that creating the socket, binding it to an address, and listen are all handled outside the loop, and accept() and starting threads are inside the loop.

You may want to wrap this entire block inside another thread; that is acceptable. The important part is separating the listen from the accept and per-client thread. This allows your code to stop accepting new connections but handle existing clients until they disconnect, or disconnect existing connections when they use their allotment of resources but continue accepting connections, etc. (Note how your last catch block will terminate the server if any single client socket throws an exception; that kind of code is easy to avoid with the usual server layout.)

Upvotes: 3

EKS
EKS

Reputation: 5623

replace

                                ServThread.Abort();                                    
                                return;

with a continue instead, this will not break the while loop and yet stop the current "round". Please consider reading this: http://www.codeproject.com/KB/IP/serversocket.aspx nice project to build from

Upvotes: 2

Related Questions