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):
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):
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?
//РАБОТА С ВХОДНЫМИ ДАННЫМИ while (true)
never exit this cycle again. - Grundy