#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
В подобных случаях обычно делают один поток слушатель, который прослушивает нужный порт. Когда подключается клиент создаётся новый поток для обслуживания непосредственно его и слушатель передаёт работу с клиентом этому потоку. При завершении клиентом работы с сервером этот поток уничтожается. Приблизительно как-то так.
Комментариев нет:
Отправить комментарий