There is an SMTP service. He listens to port 25:
SMTP_Listener = new TcpListener(IPAddress.Any, 25); SMTP_Listener.Start();
It turns out that when teams of 2 or more clients send him, they “merge” and it turns out like this (example):
- Client1: command "HELLO 11111"
- Client2: team "HELLO 22222"
- Client3: team "HELLO 33333"
I get "HELLO 11" from the first client, from the second one - "LO 22", for the third one - "LO 3333" (for example).
Tell me how to properly separate reading from several clients?
Each client works for me in a separate stream.
Client Receive Code:
/// <summary> /// Считываем команду клиента /// </summary> /// <returns></returns> private string ReadLine() { try { long lastDataTime = DateTime.Now.Ticks; ArrayList lineBuf = new ArrayList(); byte prevByte = 0; while (true) { if (clientSocket == null) l.Write(" !!! clientSocket is NULL"); if (!clientSocket.Connected) l.Write(" !!! сокет не включен!"); if (clientSocket.Available > 0) { // Read next byte byte[] currByte = new byte[1]; int countRecieved = clientSocket.Receive(currByte, 1, SocketFlags.None); // Count must be equal. Eg. some computers won't give byte at first read attempt if (countRecieved == 1) { lineBuf.Add(currByte[0]); // Line found if ((prevByte == (byte) '\r' && currByte[0] == (byte) '\n')) { byte[] retVal = new byte[lineBuf.Count - 2]; // Remove <CRLF> lineBuf.CopyTo(0, retVal, 0, lineBuf.Count - 2); return System.Text.Encoding.Default.GetString(retVal).Trim(); } // Store byte prevByte = currByte[0]; //l.Write("prevByte = " + prevByte); //// Check if maximum length is exceeded //if (lineBuf.Count > maxLen) //{ // throw new Exception( "Maximum line length exceeded"); //} // reset last data time lastDataTime = DateTime.Now.Ticks; //l.Write("lastDataTime = " + lastDataTime); } } else { // l.Write("clientSocket.Available: " + clientSocket.Available.ToString()); // тут всегда 0 //---- Time out stuff -----------------------// if (DateTime.Now.Ticks > lastDataTime + ((long)(60000)) * 10000) { l.Write("ERROR: Read timeout: " + (((long)(60000)) * 10000).ToString()); //clientSocket.Close(); l.Write("Сокет закрыт из-за простоя в " + (((long)(60000)) * 10000).ToString() + " м-сек."); // throw new Exception("Read timeout"); return ""; // ????????????????????????????????????????????????????????????????????? } System.Threading.Thread.Sleep(100); //------------------------------------------// } } } catch (Exception x) { l.Write("EROR ReadLine(): " + x.ToString()); throw new Exception(x.Message); } }
UPD:
public void Listen() { int iter = 0; try { l.Write("***************START*******************"); l.Write("SMTP server started " + DateTime.Now.ToString()); 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); l.Write("New session: " + _sessionId); //и в отдельный поток его Thread newClient = new Thread(StartProcessing); l.Write("Создан поток для обработки клиента " + _sessionId); UserSessionController.AddSession( Convert.ToInt32(_sessionId ) ); newClient.Name = _sessionId; newClient.IsBackground = true; // ??? newClient.Start(); } } catch (Exception ex) { l.Write("SMTP Listen Error: " + ex.ToString()); throw; } }
ReadLine
procedure. Do you have a commonclientSocket
at all? - VladDNetworkStream
and use some higher level functions? - VladD