I wrote the SMTP server, but it works incorrectly at what point: if I connect to it via telnet once, it will respond normally (Figure 1-2.), But if I connect again through another cmd console, then I will only appear black screen and everything (Fig. 3):

enter image description here (pic 1)

enter image description here (pic 2)

enter image description here (pic 3)

In the latter case, whatever I entered, nothing will appear on the screen, and it will not even be logged by my SMTP.

In the first case, my commands are displayed in the console, they are logged by the server and I see the answer in this console (Figure 4):

enter image description here (pic 4)

Ie, what I see is that one client connects to it, the server works fine, in all other cases it does not work correctly ( right? )

Here is how I implemented the SMTP server (this is a win-service):

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

QUESTION:

Can you please tell me how to make my service equally able to serve all connected clients, and not just the first one?

  • logging in once here: //РАБОТА С ВХОДНЫМИ ДАННЫМИ while (true) never exit this cycle again. - Grundy

1 answer 1

In such cases, usually one stream is made by a listener who listens on the required port. When a client connects, a new thread is created for servicing it directly and the listener transfers work with the client to that thread. When the client finishes working with the server, this thread is destroyed.

Something like that.

  • Thank you, problem solved! - Leonard Bertone