何时关闭tcpclient和networkstream

时间:2014-04-30 06:59:51

标签: c# service tcp tcpclient networkstream

我正在编写一个客户端应用程序(Windows服务),它定期从服务器读取数据并将数据写入服务器。服务器配置为如果理解了他收到的帧,则始终回复客户端。我有以下发送和接收方法:

 public byte[] Sendmessage(byte[] arrbMessage)
    {
        byte[] arrbDataInput;                                               // byteArray for received data

        try
        {
            _oStream = _oClient.GetStream();                                // try to get a networkstream
        }
        catch (InvalidOperationException e)
        {
            Connect();                                                      // if this fails, tcpclient is probably disconnected, reconnect client and networstream
        }

        if (_oClient.Connected)
            try
            {                                                               // Send the arrbMessage to the connected TcpServer.
                string sKey = "123456789ABC";
                byte[] arrbMessageEncrypted = EncryptedFrame(arrbMessage, sKey);                

                if (_oStream.CanWrite)                                      // if stream is available for writing
                {
                    _oStream.Write(arrbMessageEncrypted, 0, arrbMessageEncrypted.Length);     //send message
                    _oStream.Flush();                                       //Clear stream
                }
                // Receive the TcpServer.response. 
                if (_oStream.CanRead)                                       // if stream is available for reading
                {
                    arrbDataInput = new byte[256];                          // set inputbuffer to 256
                    //_oClient.NoDelay = true;                                // don't wait if nothing is received
                    // Read the first batch of the TcpServer response bytes.
                    _oStream.ReadTimeout = 2000;
                    Int32 bytes = _oStream.Read(arrbDataInput, 0, arrbDataInput.Length); //read out data, put datalength in "bytes"
                    Array.Resize(ref arrbDataInput, bytes);                 // resize array to length of received data

                    _oStream.Close();                                       // close the network stream

                    if (arrbDataInput.Length > 0)
                    {
                        byte[] arrbMessageDecrypted = DecryptedFrame(arrbDataInput, sKey);

                        if (CheckBusy(arrbMessageDecrypted))
                        throw new ArgumentNullException();

                        return arrbMessageDecrypted;
                    }
                    return null;                                   // return the received data
                }
            }
            catch (ArgumentNullException e)
            {
                return Sendmessage(arrbMessage);
            }
            catch (SocketException e)
            {
            }
            catch (System.IO.IOException e)
            {
                while (!_oClient.Connected)
                {
                    Connect();
                }
            }
        else
        {
            while (!_oClient.Connected)
            {
                Connect();
            }
        }
        return null;
    }

我在打开流时遇到了很多困难,所以目前我们在发送和接收数据后每次都关闭它。我应该离开流和tcpclient吗?该功能定期调用。

1 个答案:

答案 0 :(得分:4)

我参与了一个应用程序,其中NetworkStream在应用程序启动时打开,仅在以下场景中关闭:

  • 应用程序已关闭 - (该应用程序主要连续运行数月)。
  • 网络连接丢失 - (非常可靠的千兆以太网+ 100 + Mbps MPLS)超时后,tcpClient.Connected属性将返回false并关闭NetworkStream和{ {1}}。然后我们启动一个每秒计时器,它将检查服务器的可用性,一旦找到服务器,它就会重新连接,从而打开TcpClientTcpClient
  • 服务器正在关闭 - (非常非常罕见)服务器发送断开连接信号,导致客户端应用程序关闭NetworkStreamNetworkStream并启动轮询线程检查服务器的可用性。

我们没有发现任何阻止NetworkStream和TcpClient打开的问题。 也许代码的其他部分可能会导致问题。


脱离上下文,但建议:当您从TcpClient阅读时,您正在阅读256字节;如果数据长于256个字节怎么办?

我会为每组数据建议一些分隔符;例如如果您的加密系统生成Base64哈希,您可以安全地使用';' (分号)作为数据分隔符。 (我们使用\ n作为命令的分隔符)但它完全取决于您的场景。

此外,使用以下类型的逻辑来读取和存储接收的字符串,并仅在分隔符可用时解密和执行。这将确保您永远不会收到部分字符串并尝试解密。

NetworkStream