Reputation: 5008
In the code below I have a StreamReader reading from a network stream. This code normally will run fine for days. I ran into a problem where all of a sudden StreamReader.ReadLine() started returning null.
According to Microsoft documentation StreamReader.ReadLine() will return null when it has reached the end of the input stream. This doesn't make sense to me when the underlying stream is a NetworkStream. Shouldn't ReadLine() just block until the network stream receives data?
This is the first time I ran into this problem and I have not been able to duplicate it. What could cause this?
Context: the application receives CDR records from a phone switch. The phone switch connects to the application and sends plain old text records. After the switch connects it will remain connected and keep sending records for eternity unless something breaks.
private void ProcessClient(TcpClient client)
{
try
{
using (NetworkStream stream = client.GetStream())
{
using (StreamReader reader = new StreamReader(stream))
{
//continue processing while service is on
while (m_RunService & client.Connected)
{
string curLine = reader.ReadLine();
//code here does stuff to string
//will catch any exceptions that have to do with
//processing the string
}
}
}
}
catch (Exception ex)
{
//write to log
}
}
Here is the code that starts the listener:
private void Listen()
{
try
{
while (m_RunService)
{
try
{
m_TcpClient = m_TcpListener.AcceptTcpClient();
//run on same thread, should only ever be 1 cnx at a time
ProcessClient(m_TcpClient);
}
catch (Exception ex)
{
//write to log
}
finally
{
m_TcpClient.Close();
}
}
}
finally
{
m_TcpListener.Stop();
}
}
Upvotes: 4
Views: 6794
Reputation: 793
If the NetworkStream
does not have data available, the call to ReadLine()
will return null because it assumes it has reached the end of the stream.
Try checking NetworkStream.CanRead
and NetworkStream.DataAvailable
before calling ReadLine
. If the connection has not closed, manually block for a time then try your read again.
EDIT
You can check to see if the connection is still open by making a Send
or using the underlying Socket
:
The Connected property gets the connection state of the Socket as of the last I/O operation. When it returns false, the Socket was either never connected, or is no longer connected.
The value of the Connected property reflects the state of the connection as of the most recent operation. If you need to determine the current state of the connection, make a nonblocking, zero-byte Send call. If the call returns successfully or throws a WAEWOULDBLOCK error code (10035), then the socket is still connected; otherwise, the socket is no longer connected.
Upvotes: 1
Reputation: 1503689
The StreamReader
will block until it receives data or the connection is closed. It sounds like an exception occurred at the server side, it closed the connection, and the client side received no data.
Upvotes: 5
Reputation: 1064164
That pretty much sounds like the stream has closed. Otherwise yes: it would block. My guess: network #fail
Upvotes: 0