我有这个TcpClient代码可以正常工作。它连接到Linux系统上的perl服务器并接收服务器发送给它的任何东西。很好地工作。
public static void Main() {
foreach (ProtocolConnection tcpConnection in TcpConnectionsList) {
ProtocolConnection connection = tcpConnection;
ThreadPool.QueueUserWorkItem(_ => {
ThreadTcpClient(connection);
ManualResetEventTcp.Set();
});
}
... Some code...
}
public static void TcpConnect(ProtocolConnection varConnection) {
int retryCountSeconds = varConnection.RetryEverySeconds*Program.MilisecondsMultiplier;
int count = 0;
while (true) {
try {
using (var client = new TcpClient(varConnection.IpAddress.ToString(), varConnection.Port) { NoDelay = true })
using (var stream = client.GetStream()) {
var data = new Byte[256];
while (!Program.PrepareExit) {
Int32 bytes = stream.Read(data, 0, data.Length);
string varReadData = Encoding.ASCII.GetString(data, 0, bytes).Trim();
if (varReadData != "" && varReadData != "PONG") {
VerificationQueue.EnqueueData(varReadData);
Logging.AddToLog("[TCP][" + varConnection.Name + "][DATA ARRIVED]" + varReadData);
} else {
Logging.AddToLog("[TCP]" + varReadData);
}
}
}
} catch (Exception e) {
if (e.ToString().Contains("No connection could be made because the target machine actively refused it")) {
Logging.AddToLog("[TCP][ERROR] Can't connect to server (" + varConnection.Name + ") " + varConnection.IpAddress + ":" + varConnection.Port );
} else {
Logging.AddToLog(e.ToString());
}
}
DateTime startTimeFunction = DateTime.Now;
do {
Thread.Sleep(1000);
} while (((DateTime.Now - startTimeFunction).TotalSeconds < retryCountSeconds));
}
}
然而,在某些情况下,我遇到了一些问题:
string varReadData = Encoding.ASCII.GetString(data, 0, bytes).Trim();
也没有超时,所以当PONG没有到达时,我的客户端甚至都没有注意到它。它只是在等待...这让我... .. string varReadData = Encoding.ASCII.GetString(data, 0, bytes).Trim();
这一直在等待数据。当服务器崩溃或断开我的客户端时,我甚至都没有注意到。我希望服务器有某种timeout
或检查连接是否有效。如果它不活动,它应该尝试重新连接。 修复此TcpClient最简单的方法是什么?我如何实现双向通信,确保如果服务器丢失我的连接或我的网络断开客户端将注意到它并重新建立连接?
答案 0 :(得分:5)
Encoding.ASCII.GetString(data, 0, bytes).Trim();
永远不会阻挡,stream.Read()
如果您正在阅读,则无法轻易区分丢弃连接的服务器(或其间的任何NAT网关),以及服务器根本没有任何内容可以发送给您的情况。如果TCP FIN / RST数据包在发生故障时无法到达您的客户端,或者NAT网关静默地断开您的连接,则为Atleast。
你可以做什么;
最后一点将告诉您tcp连接是否失败,它不会告诉您服务器是否有一些失败 - 例如如果你用CTRL + Z你的perl服务器,它就会在tcp窗口关闭的情况下不做任何事情,所以如果你需要,你可能需要实现自己的热量消息来覆盖这样的情况。
答案 1 :(得分:2)
您应该摆脱UDP心跳尝试并输入real TCP heartbeat。使用UDP“ping”服务器几乎没有意义。
您的协议也缺失message framing。
仔细阅读这些链接文章(特别是邮件框架)。您当前使用的协议确实需要严格修改。