Страницы

Поиск по вопросам

пятница, 13 марта 2020 г.

Самописный СМТП-сервер

#c_sharp #многопоточность #smtp


Я написал СМТП сервер, но работает он некорректно вот в каком моменте: 
если я 1 раз подключусь к нему через телнет, он ответит нормально (рис 1-2.), но
если я еще раз подключусь через другую консоль cmd, то я появится только черный экран
и все(рис3):


(рис 1)


(рис 2)


(рис 3)

В последнем случае что-бы я ни вводил, на экране ничего не отобразится, и даже не
залогируется моим СМТП

В первом же случае, мои команды отображаются в консоли, они логируюстя сервером и
я вижу в этой консоли ответ (рис 4):


(рис 4)

Т.е., что я вижу, один клиент к нему подключается, работает нормально сервер, во
всех остальных случаях он работает не корректно (верно?)

Вот как я реализовал СМТП-сервер (это win-сервис):

 protected override void OnStart(string[] args)
        {
SmtpHelper s = new SmtpHelper(this);
System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(StartListen),
(object)s );
}

 void StartListen(object s)
        {
            try
            {
                var a = (SmtpHelper)s;
                a.Listen(); //запуск 
            }
            catch (Exception ex)
            {
                l.Write("Error (StartListen(object s)): " + ex.ToString());
                throw;
            }

        }




public void Listen()
        {
            try
            {
                SMTP_Listener = new TcpListener(IPAddress.Any, port); 
                SMTP_Listener.Start();

                while (true)
                {
                    clientSocket = SMTP_Listener.AcceptSocket();

                    _sessionId = clientSocket.GetHashCode().ToString();

                    _email.sessionId = Convert.ToInt32(_sessionId);


                    StartProcessing(newController);
                    l.Write("we are there");

                   // System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(ClientThread),
SMTP_Listener.AcceptTcpClient());
                }

            }
            catch (Exception ex)
            {
                l.Write("SMTP Listen Error: " + ex.ToString());
                throw;
            }
        }



void StartProcessing(ClientSessionController newController)
        {

            try
            {
                m_ConnectedIp = ParseIP_from_EndPoint(clientSocket.RemoteEndPoint.ToString());
                m_ConnectedHostName = GetHostName(m_ConnectedIp);

                _email.ip = m_ConnectedIp;
                _email.port = 25;


                SendData("220 " + System.Net.Dns.GetHostName() + " Service ready\r\n");

                //if (!clientSocket.Connected)
                //    clientSocket.Connect(IPAddress.Any, port);

                //РАБОТА С ВХОДНЫМИ ДАННЫМИ
                while (true)
                {
                    //если есть данные, то считаем их
                    if (clientSocket.Available > 0)
                    {
                        //получение команды от клиента
                        string lastCmd = ReadLine();

                        //парсим команду от клиента (HELO, RCPT, DATA etc.)
                        if (lastCmd.Trim() != String.Empty)
                            ProceedCommand(lastCmd, newController);
                        //break;
                    }
                    else
                    {
                      //dump:  l.Write("[Socket isn't available now]");
                    }
                }               
            }
            catch (Exception ex)
            {
                throw;
            }

        }


ВОПРОС: 

Подскажите пожалуйста, как мне сделать так, чтобы мой сервис мог одинаково обслужить
всех подключаемых клиентов, а не только первого?
    


Ответы

Ответ 1



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

Комментариев нет:

Отправить комментарий