My server receive some TCP/IP data and response to client:
private static void startClient(TcpClient clientSocket)
{
NetworkStream networkStream = null;
DateTime fecha = DateTime.Now;
try
{
clientSocket.NoDelay = true;
networkStream = clientSocket.GetStream();
string receiveData = readData(clientSocket);
string responseData = "abc"; //ProcessData(receiveData);
if (responseData != null)
writeData(networkStream, responseData);
}
catch (SocketException e)
{
throw;
}
finally
{
networkStream.Close();
}
}
private static string readData(TcpClient tcpClient)
{
try
{
var bytesFrom = new byte[tcpClient.ReceiveBufferSize];
StringBuilder dataFromClient = new StringBuilder();
int readCount;
while ((readCount = tcpClient.GetStream().Read(bytesFrom, 0, tcpClient.ReceiveBufferSize)) != 0)
{
dataFromClient.Append(Encoding.ASCII.GetString(bytesFrom, 0, readCount));
}
//int bytesRead = tcpClient.GetStream().Read(bytesFrom, 0, tcpClient.ReceiveBufferSize);
//string dataFromClient = Encoding.ASCII.GetString(bytesFrom, 0, bytesRead);
return dataFromClient.ToString();
}
catch (SocketException e)
{
throw;
}
}
private static void writeData(NetworkStream networkStream, string dataToClient)
{
Byte[] sendBytes = null;
try {
sendBytes = Encoding.ASCII.GetBytes(dataToClient);
networkStream.Write(sendBytes,0, sendBytes.Length);
networkStream.Flush();
}
catch(SocketException e)
{
throw;
}
}
With this solution the client never receives the response sent:
http://postimg.org/image/6srtslf2f/
However changing the reception to a single call to NetworkStream.Read ...
private static string readData(TcpClient tcpClient)
{
try
{
var bytesFrom = new byte[tcpClient.ReceiveBufferSize];
int bytesRead = tcpClient.GetStream().Read(bytesFrom, 0, tcpClient.ReceiveBufferSize);
string dataFromClient = Encoding.ASCII.GetString(bytesFrom, 0, bytesRead);
return dataFromClient.ToString();
}
catch (SocketException e)
{
throw;
}
}
... the client receives the response
http://postimg.org/image/uih9hadfr/
UPDATE
I found solution here. I´ve fixed it using 2/3 ways described . First handle EOS end message. Seccond is setting receive timeout if client works bad and sends bad data without EOS:
private static string readData(TcpClient tcpClient)
{
var clientStream = tcpClient.GetStream();
var dataFromClient = string.Empty;
var buffer = new byte[RECEIVE_BUFFER_SIZE];
if (!clientStream.CanRead)
return "";
tcpClient.ReceiveTimeout = RECEIVE_TIMEOUT;
try
{
int readCount;
while ((readCount = clientStream.Read(buffer, 0, buffer.Length)) != 0)
{
dataFromClient += Encoding.ASCII.GetString(buffer, 0, readCount);
if (dataFromClient.EndsWith(EOS))
return dataFromClient;
}
return dataFromClient.ToString();
}
catch (Exception ex)
{
var socketExept = ex.InnerException as SocketException;
if (socketExept != null && socketExept.SocketErrorCode == SocketError.TimedOut)
Logger.Warn(string.Format("Se excedio el timeout de recepcion: {0} ms",RECEIVE_TIMEOUT));
else
Logger.Error(string.Format("Error leyendo el mensaje recibido"), ex);
return dataFromClient.ToString();
}
}