I have worked on an application in which the NetworkStream
was opened when the application started and was closed only in following scenarios:
- Application was closed - (that application mostly runs continuously for months).
- Network connection is lost - (very reliable gigabit ethernet + 100+Mbps MPLS) after timeout, the
tcpClient.Connected
property will return false and we close theNetworkStream
andTcpClient
. Then we start a per second timer which will check for the availability of server and as soon as the server is found, it reconnects thereby opening theTcpClient
andNetworkStream
- Server is shutting down - (very very rare) server sends the disconnect signal which causes the client application to close the
NetworkStream
and theTcpClient
and start the polling thread to check availability of the server.
We have not observed any issue for keeping the NetworkStream and TcpClient open. Maybe there are other parts of code which may be causing issues.
Out of context, but a suggestion: When you are reading from NetworkStream
, you are reading ony 256 bytes; what if the data is longer than 256 bytes?
I would suggest some separator for each set of data; e.g. if your encryption system generates Base64 Hashes, you can safely use ';' (semicolon) as the data separator. (We are using \n as separator of commands) but it totally depends on your scenario.
Also, use the following type of logic to read and store the received string, and decrypt and execute only when the separator character is available. This will ensure that you are never receiving a part string and attempting a decrypt of that.
string allPendingCommands = "";
string commandSeparator = ";"; // your command separator character here
while(tcpClient.Connected)
{
if (!networkStream.DataAvailable)
System.Threading.Thread.Sleep(100);
// you can change it depending on the frequency of availability of data
// read 256 bytes into you array
// convert the byte[] to string
// add the newly read text to the text remaining from previous command execution.
allPendingCommands += theReadBytes;
while(allPendingCommands.Contains(commandSeparator))
{
// it may happen that the string at the moment contains incomplete
// string, which can also not be decoded/decrypted. This loop will
// stop and the next 256 bytes (as much available) will be read and
// appended into allPendingCommands. When the command gets completed,
// allPendingCommands will contain the separator character and the
// command will be properly decoded and executed.
int idx = allPendingCommands.IndexOf(commandSeparator);
string command = allPendingCommands.SubString(0, idx);
allPendingCommand = allPendingCommand.SubString(idx + 1);
// convert those bytes back to string (after decrypting/decoding)
command = Decrypt(command);
// Process the Command (command); // do the needful in the function
}
}