gpt4 book ai didi

c# - 何时关闭 tcpclient 和 networkstream

转载 作者:可可西里 更新时间:2023-11-01 02:37:13 25 4
gpt4 key购买 nike

我正在编写一个客户端应用程序(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 打开吗?该函数被定期调用。

最佳答案

我开发过一个应用程序,其中 NetworkStream 在应用程序启动时打开,仅在以下情况下关闭:

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

我们没有观察到保持 NetworkStream 和 TcpClient 打开的任何问题。 可能是代码的其他部分导致了问题。


断章取义,但建议:当您从NetworkStream 读取时,您只读取了256 个字节;如果数据超过 256 字节怎么办?

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

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

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
}
}

关于c# - 何时关闭 tcpclient 和 networkstream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23381627/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com