如何为多个TCP连接指定连接和发送的超时(以毫秒为单位)?

时间:2013-06-11 15:16:53

标签: perl sockets timeout

我有多个阻止TCP客户端尝试连接并向服务器发送数据。但是,每个操作的时间不应超过500毫秒,因为数据与时间有关。超时时,应该再试一次。我见过alarm()方法,但只接受秒。这样做有好办法吗?

2 个答案:

答案 0 :(得分:2)

Time::HiRes模块为您提供了具有微秒粒度的函数ualarm

答案 1 :(得分:2)

如果您有每个连接的子进程,则可以使用Time::HiResualarm。否则,我不明白为什么你甚至想要使用alarm。它甚至不会帮助线程(因为信号被发送到进程)。

更好的方法是记下建立连接的时间,如果从接下来的0.5秒后接收到来自客户端的数据,则删除连接。 Time :: HiRes提供了一个返回小数秒的time版本。

无论您如何提供并行性(线程,子进程,select,非阻塞操作),此方法都有效。它适用于TCP和UDP。它甚至可以携带。

如果所有内容都在同一个线程和进程中,那么每当从任何连接获取数据时,都可以通过扫描所有连接超时来尽快删除死连接。


alarm不会帮助您使用线程。

  1. 如果在启动线程之前设置处理程序,则线程中的调用不会中断。

    use strict;
    use warnings;
    use threads;
    
    use Time::HiRes qw( time ualarm );
    
    local $SIG{ALRM} = sub { };
    
    {
       ualarm(2 * 1_000_000);
       my $s = time;
       sleep(5);
       my $e = time;
       print "Slept for ".($e-$s)." seconds\n";
    }
    
    for my $thread_idx (0..1) {
       async {
          ualarm(2 * 1_000_000) if $thread_idx == 0;
          my $s = time;
          sleep(5);
          my $e = time;
          print "Thread $thread_idx slept for ".($e-$s)." seconds\n";
       };
    }
    
    $_->join for threads->list;
    

    输出

    Slept for 2.00284504890442 seconds
    Thread 0 slept for 5.00048089027405 seconds
    Thread 1 slept for 5.00327205657959 seconds
    
  2. 在线程中设置处理程序根本没有任何影响。

    use strict;
    use warnings;
    use threads;
    
    use Time::HiRes qw( time ualarm );
    
    for my $thread_idx (0..1) {
       async {
          local $SIG{ALRM} = sub { };
          ualarm(2 * 1_000_000) if $thread_idx == 0;
          my $s = time;
          sleep(5);
          my $e = time;
          print "Thread $thread_idx slept for ".($e-$s)." seconds\n";
       };
    }
    
    $_->join for threads->list;
    

    输出

    Alarm clock