关于 c#:Detecting drop connections | 珊瑚贝

Detecting dropped connections


我有一台服务器和许多客户端。服务器需要知道客户端何时非正常断开连接(不发送 TCP FIN),以便它没有与该客户端关联的挂起连接和其他一次性对象。

无论如何,我读了这篇文章并决定从链接的博客中添加一个”keepalive 消息到应用程序协议”(仅包含头字节)和”假设最坏的显式计时器”方法。

当客户端连接时(顺便说一句,我正在使用 TcpListener 和 TcpClient),服务器启动一个 System.Threading.Timer 倒计时 30 秒。每当服务器从该客户端接收到某些内容时,它都会重置计时器。当计时器达到 0 时,它会断开用户并处理它需要处理的任何内容。客户端应用程序也有一个计时器,当用户在 15 秒内(服务器值的一半,只是为了确定)没有发送任何内容时,它会发送 keepalive 消息。

我的问题是,有没有更简单的方法来实现这一点?也许 TcpClient 上有一些选项?我尝试使用 TcpClient.ReceiveTimeout,但这似乎不适用于 ReadAsync。

  • 正如斯蒂芬指出的那样,在应用程序协议中使用心跳消息是确保连接处于活动状态并且两个应用程序都正常运行的唯一可靠方法。请注意,许多工程师已经创建了一个心跳线程,即使应用程序线程失败,它也会继续运行。您需要确保心跳构成解决方案的操作结构的一部分。这是一个不平凡的问题。
  • 对于异步套接字操作,我转向了这段代码,我已经成功使用了 blogs.msdn.com/b/pfxteam/archive/2011/12/15/10248293.aspx 我已经使用了 SocketAwaitable
  • 谢谢!我将尝试该代码,但我不太明白您所说的”您需要确保心跳构成解决方案的操作结构的一部分”是什么意思。
  • 我的意思是,如果您的解决方案有一个或多个线程来发送消息并执行业务逻辑,以及一个单独的线程来发送心跳消息,那么最终可能会出现正在发送心跳消息的情况,但应用程序线程出现故障。最终,您需要确保仅当您有理由确定应用程序正常运行并且没有线程出现故障(停止)时才发送心跳消息。心跳应该完全集成到解决方案中。
  • 啊,有道理。再次感谢!


正如 Stephen 指出的那样,在应用程序协议中使用心跳消息是确保连接处于活动状态并且两个应用程序都正常运行的唯一可靠方法。请注意,许多工程师已经创建了一个心跳线程,即使应用程序线程发生故障,它也会继续运行。

使用这里的类将解决您的异步套接字问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public sealed class SocketAwaitable : INotifyCompletion
{
    private readonly static Action SENTINEL = () => { };

    internal bool m_wasCompleted;
    internal Action m_continuation;
    internal SocketAsyncEventArgs m_eventArgs;

    public SocketAwaitable(SocketAsyncEventArgs eventArgs)
    {
        if (eventArgs == null) throw new ArgumentNullException(“eventArgs”);
        m_eventArgs = eventArgs;
        eventArgs.Completed += delegate
        {
            var prev = m_continuation ?? Interlocked.CompareExchange(
                ref m_continuation, SENTINEL, null);
            if (prev != null) prev();
        };
    }

    internal void Reset()
    {
        m_wasCompleted = false;
        m_continuation = null;
    }

    public SocketAwaitable GetAwaiter() { return this; }

    public bool IsCompleted { get { return m_wasCompleted; } }

    public void OnCompleted(Action continuation)
    {
        if (m_continuation == SENTINEL ||
            Interlocked.CompareExchange(
                ref m_continuation, continuation, null) == SENTINEL)
        {
            Task.Run(continuation);
        }
    }

    public void GetResult()
    {
        if (m_eventArgs.SocketError != SocketError.Success)
            throw new SocketException((int)m_eventArgs.SocketError);
    }
}


来源:https://www.codenong.com/38117334/

微信公众号
手机浏览(小程序)

Warning: get_headers(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57

Warning: get_headers(): Failed to enable crypto in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57

Warning: get_headers(https://static.shanhubei.com/qrcode/qrcode_viewid_9024.jpg): failed to open stream: operation failed in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57
0
分享到:
没有账号? 忘记密码?