我有一个如下的tcp连接:
public void ConnectToServer()
{
string mac = GetUID();
while(true)
{
try
{
tcpClient = new TcpClient("xx.x.xx.xxx", xxxx);
networkstream = new SslStream(tcpClient.GetStream());
networkstream.AuthenticateAsClient("xx.x.xx.xxx");
networkstream.Write(Encoding.UTF8.GetBytes("0002:" + mac + "\r\n"));
networkstream.Flush();
string serverMessage = ReadMessage(networkstream);
Console.WriteLine("MESSAGE FROM SERVER: " + serverMessage);
}
catch (Exception e)
{
tcpClient.GetStream().Close();
tcpClient.Close();
}
}
}
这很好,可以向服务器发送接收数据。
我需要帮助,如果服务器在客户端启动时没有运行,它会等待,然后在服务器启动后再连接。但是,如果客户端和服务器都在运行且一切正常,如果我关闭服务器,客户端将不会重新连接(因为我还没有任何东西可以处理该事件)。
我在这里看到了一些建议投票的答案。这是唯一的方法吗?我调用的ReadMessage方法也进入无限循环。如果需要,我可以发布该代码。
我真的想检测服务器何时关闭/崩溃并关闭流和tcpclient并重新连接ASAP。
这是我的readmessage:
static string ReadMessage(SslStream sslStream)
{
if (sslStream.CanRead)
{
byte[] buffer = new byte[2048];
StringBuilder messageData = new StringBuilder();
int bytes = -1;
string message_type = null;
string actual_message = null;
do
{
try
{
Console.WriteLine("LENGTH: " + buffer.Length);
bytes = sslStream.Read(buffer, 0, buffer.Length);
Decoder decoder = Encoding.UTF8.GetDecoder();
char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
decoder.GetChars(buffer, 0, bytes, chars, 0);
messageData.Append(chars);
message_type = messageData.ToString().Substring(0, 5);
actual_message = messageData.ToString().Substring(5);
if (message_type.Equals("0001:"))
{
m_Window pop = new m_Window();
pop.callHttpPost(null, new EventArgs());
}
if (messageData.ToString().IndexOf("\r\n") != -1)
{
break;
}
}
catch (Exception e)
{
Console.WriteLine("ERROR: " + e.Message);
}
} while (bytes != 0);
return messageData.ToString();
}
return("CONNECTION HAS BEEN LOST");
}
答案 0 :(得分:2)
使用TCP,您有两种服务器断开连接:
当服务器关闭时,您将在客户端套接字上接收0字节,这就是您知道对等端已关闭其套接字结尾的方式,这称为半关闭。 但是如果服务器崩溃,事情会变得更加丑陋。 当这种情况再次发生时,你有几种可能性 如果您没有从客户端向服务器发送任何内容,那么您无法发现服务器确实已崩溃。 找出服务器崩溃的唯一方法是让客户端发送内容或激活keep alive。如果您向不存在的服务器套接字发送内容,则必须等待相当长的时间,因为TCP将尝试多次,重新发送,直到有服务器响应。当TCP多次重试时,它最终会挽救,如果你有一个阻塞套接字,你会看到发送失败,这意味着你应该关闭套接字。
实际上有第三种可能的服务器断开连接,即复位,但这是特别使用的。我假设如果有一个gracefull服务器关闭,则执行服务器端套接字上的正常关闭。最终将发送FIN而不是RST,这是例外情况。
现在回到你的情况,如果服务器崩溃,它本质上是在TCP的设计中,因为所有那些重传超时和增加的延迟,你将不得不等待一段时间来实际检测到存在问题。如果服务器正常关闭并再次启动,则情况并非如此,您可以通过接收0字节立即检测到。