如何将 AnyEvent::Handler 与具有端口重用的套接字一起使用

2024-01-25

最近我遇到了一个很棒的 Perl 模块“AnyEvent”,它允许用户进行异步/事件驱动的编程。

创建了以下代码片段,效果很好。我遇到的问题是,在打开和关闭大量套接字后,它很快耗尽了所有客户端端口(“netstat -ant”显示 20,000 多个套接字处于 TIME_WAIT 状态)。

$hdl = new AnyEvent::Handle (
  connect => [$ip, $port],
  on_connect=> sub {
      my ($handle, $host, $port, $tmp) = @_;
      #print "connect routine for $handle->{ue}\r\n";
      #update states.
  },
  on_read => sub {
      my $hdl = $_[0];
      #read data
      #send response.
  });

我想知道是否可以使用 IO::Socket::INET 创建 TCP 套接字,然后在 AnyEvent::Handle 中使用新创建的套接字:

my $sock = IO::Socket::INET->new( Proto    => 'tcp',
                             PeerAddr => $ue->{vars}->{ip},
                             PeerPort => $ue->{vars}->{dstPort},
                             ReusePort => 1,
            KeepAlive => 1
) || die "failed to setup outsock $@\n";
$hdl = new AnyEvent::Handle (
  fh => $sock,
  on_connect=> sub {
      my ($handle, $host, $port, $tmp) = @_;
      #print "connect routine for $handle->{ue}\r\n";
      #update states.
  },
  on_read => sub {
      my $hdl = $_[0];
      #read data
      #send response.
  });

尝试过但不起作用。感谢任何建议/评论。

感谢 ikegami 对此进行了研究并提出了建议。但是,SO_REUSEADDR似乎没有生效。这是我使用的代码(基于他的建议)

use strict;
use warnings;

use AnyEvent           qw( );
use AnyEvent::Handle   qw( );
use AnyEvent::Impl::EV qw( );
use AnyEvent::Socket   qw( tcp_connect );
use Socket             qw( SOL_SOCKET SO_REUSEPORT SO_REUSEADDR);

my $ts = 0;
my $trans = 0;
my $currentTS;

sub transaction {
   my ($host, $port) = @_;
   tcp_connect($host, $port, sub {
      my ($sock) = @_
         or die "Can't connect: $!";

      my $handle;
      $handle = AnyEvent::Handle->new(
         fh => $sock,
         on_eof => sub {
            $handle->destroy();
         },
         on_read => sub {
            my ($handle) = @_;
            #print $handle->rbuf();
            $trans ++;
            $currentTS = time();
            if ($currentTS > $ts) {
                $ts = $currentTS;
                print "$trans\n";
            }
            #printf "recved %d bytes of data\n", length($handle->rbuf);
            # This should continue to read until header +
            # Content-Length bytes have been read instead
            # of stopping after one read.
            if (length($handle->rbuf) > 0) {
                $handle->destroy();
            }
         },
      );
      $handle->push_write("GET /s HTTP/1.1\r\nHost: $host\r\n\r\n");
      #$handle->push_shutdown();  # Done writing.
   }, sub {
      my ($sock) = @_;

      #setsockopt($sock, SOL_SOCKET, SO_REUSEPORT, 1) or die $!;
      setsockopt($sock, SOL_SOCKET, SO_REUSEADDR, 1)  or die $!;
        #   die "failed to set linger $!\n";
      return undef;
   });
}
{
   my $cv = AnyEvent->condvar();

   my $t = AnyEvent->timer(after=>0.001, interval=>1, cb=> sub {
      transaction("10.3.0.6", 80 );
   });

   $cv->recv();
}

我的系统是Ubuntu 11.04。 在目录/proc/sys/net/ipv4中,以下是两个文件的内容:

% 更多 tcp_tw_recycle

1

% 更多 tcp_tw_reuse

1


我无法运行以下命令,因为 Windows 不提供SO_REUSEPORT,但我非常有信心以下内容可以满足您的要求。

也就是说,我不确定这会有帮助。从我读到的来看,SO_REUSEPORT允许您绑定到已经活动的端口,但您不绑定到任何端口。

use strict;
use warnings;

use AnyEvent           qw( );
use AnyEvent::Handle   qw( );
use AnyEvent::Impl::EV qw( );
use AnyEvent::Socket   qw( tcp_connect );
use Socket             qw( SOL_SOCKET SO_REUSEPORT );
sub transaction {
   my ($host, $port) = @_;
   tcp_connect($host, $port, sub {
      my ($sock) = @_
         or die "Can't connect: $!";

      my $handle;
      $handle = AnyEvent::Handle->new(
         fh => $sock,
         on_eof => sub {
            $handle->destroy();
         },
         on_read => sub {
            my ($handle) = @_;
            print $handle->rbuf();

            # This should continue to read until header +
            # Content-Length bytes have been read instead
            # of stopping after one read.
            $handle->destroy();
         },
      );

      $handle->push_write("GET / HTTP/1.1\r\nHost: $host\r\n\r\n");
      $handle->push_shutdown();  # Done writing.
   }, sub {
      my ($sock) = @_;

      setsockopt($sock, SOL_SOCKET, SO_REUSEPORT, 1)
         or die $!;

      return undef;
   });
}
{
   my $cv = AnyEvent->condvar();

   my $t = AnyEvent->timer(after=>0.001, interval=>0.001, cb=> sub {
      transaction("localhost", $ARGV[0] // die("usage"));
   });

   $cv->recv();
}

用于测试的服务器:

use strict;
use warnings;
use 5.010;

use IO::Socket::INET qw( );
use Socket           qw( inet_ntoa );

my $serv = IO::Socket::INET->new(
   Listen => 1,
);

say inet_ntoa($serv->sockaddr) . ":" . $serv->sockport;

while (my $client = $serv->accept()) {
   say "Connection from ".inet_ntoa($client->peeraddr).":".$client->peerport;
   while (<$client>) {
      last if /^(?:\r?\n)?\z/;
   }

   say $client "HTTP/1.1 200 OK\r\n"
      .        "Content-Type: text/plain\r\n"
      .        "\r\n"
      .        "Hello\n";

   say "   done.";
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将 AnyEvent::Handler 与具有端口重用的套接字一起使用 的相关文章

  • 从日志尾部提取匹配行后退出

    我使用范围运算符来提取日志文件的一部分 例如 tail F logfile perl ne print if b d 现在 一旦提取的部分匹配 我就尝试退出该过程 我尝试过 tail F logfile perl ne print if b
  • 如何在Python中获取套接字的外部IP?

    当我打电话时socket getsockname 在套接字对象上 它返回我的机器的内部 IP 和端口的元组 但是 我想找回我的外部IP 最便宜 最有效的方式是什么 如果没有外部服务器的配合 这是不可能的 因为您和另一台计算机之间可能存在任意
  • 如何在 BEGIN 块之外正确声明哈希?

    考虑这个简单的程序 您能解释一下为什么在取消注释前两行后输出会有所不同吗 我的哈希发生了什么use strict 如何修复程序以供使用use strict echo e key1 nkey2 nkey3 perl lne use stric
  • 通过 SSLStream 发送数据时出现数据包碎片

    当使用 SSLStream 将 大 数据块 1 兆 发送到 已通过身份验证的 客户端时 我看到的数据包碎片 分解是FAR比使用普通 NetworkStream 时更大 在客户端上使用异步读取 即 BeginRead 会重复调用 ReadCa
  • 为什么使用自动激活文件句柄的三参数开放调用是 Perl 最佳实践?

    我有两个关于 Perl 的问题open功能 1 我好像记得从Perl 最佳实践的 3 参数版本open比两个参数版本更好 例如 open OUT gt gt file vs open OUT gt gt file 这是为什么 前几天我试图告
  • gethostbyname() 或 getnameinfo() 如何在后台工作?

    How gethostbyname or getnameinfo 在后台工作 include
  • 如何在 perl 程序中查找打开的全局文件句柄

    我刚刚发现一个问题 我必须关闭所有打开的文件句柄才能让我的 Apache cgi 脚本继续 我将问题追溯到 Parse RecDescent usr bin env perl use strict use warnings use feat
  • 找不到 DBI.pm

    我正在尝试启动这个脚本 usr bin perl use DBI my dbh DBI gt connect dbi Oracle host lonlin2 sid TIMFX1AD port 1524 xbsesdbo xbsesdbo1
  • 将相同匹配模式的连续 2 行放入单行中

    我想解析这组行 以便如果得到相同的模式 例如 lt email protected cdn cgi l email protection gt 在连续的行中 它应该以单行形式打印 并在两行之间使用 q2VDWKkY010407 222187
  • 为什么Apache MPM prefork.c 使用互斥体来保护accept()?

    我坐下来读书Apache 的 MPM prefork c http code metager de source xref apache httpd server mpm prefork prefork c这段代码使用了一个名为accept
  • java.net.SocketException:无效参数:与 BungeeCord 连接

    我编写了一个使用 gRPC 连接到服务器的 Java 依赖项 在我的 spigot 插件和普通 java 项目中使用此依赖关系工作正常 但在 BungeeCord 插件中使用它会产生以下异常 Caused by io grpc netty
  • 同步 I/O 是否会使线程繁忙?

    假设我正在同步 I O 套接字上执行 I O 该套接字已准备好read or write手术 这意味着调用线程不会在操作上被阻塞 无论非阻塞 SOCK NONBLOCK 套接字的阻塞性质 但以下事情我不清楚 实际转移何时发生 当套接字标记为
  • 如何编写 Perl 脚本来使用 curl 处理 URL?

    我有一个非常简单的任务 我有一个 crontab 每小时运行一个脚本 该脚本旨在简单地处理 URL 这就是我所拥有的 这不起作用 我收到语法错误 usr bin perl curl http domain com page html 我已经
  • Perl 的反引号、system 和 exec 有什么区别?

    有人可以帮帮我吗 在 Perl 中 以下之间有什么区别 exec command and system command and print command 还有其他方法可以运行 shell 命令吗 exec 执行命令并一去不复返 这就像一个
  • 如何强制关闭 TcpListener

    我有一个通过 tcpListener 进行通信的服务 问题是当用户重新启动服务时 抛出 地址已在使用 异常 并且服务在几分钟左右无法启动 有没有办法告诉系统终止旧连接 以便我可以打开一个新连接 我不能只使用随机端口 因为服务无法通知客户端端
  • 你能挽救我的负面回顾示例来传达数字吗?

    在 高级正则表达式 一章中掌握 Perl http oreilly com catalog 9780596527242 我有一个损坏的示例 我无法找到一个很好的修复方法 这个例子可能为了自己的利益而试图变得太聪明 但也许有人可以帮我解决它
  • 在 Ubuntu 中执行 .cgi 文件

    我在 Ubuntu 下运行 Apache PHP 当我运行 cgi 文件时 通过http localhost mycgi cgi 浏览器将显示代码而不是运行它 如何让浏览器执行 CGI 文件而不是显示其内容 将这些行添加到您的 apache
  • 使用 -T 开关运行时 $ENV{ENV} 不安全

    当我尝试最后一个例子时perlfaq5 如何计算文件中的行数 http perldoc perl org perlfaq5 html How do I count the number of lines in a file 我收到一条错误消
  • 套接字的读写如何同步?

    我们创建一个套接字 在套接字的一侧有一个 服务器 在另一侧有一个 客户端 服务器和客户端都可以向套接字写入和读取 这是我的理解 我不明白以下事情 如果服务器从套接字读取数据 它在套接字中是否只看到客户端写入套接字的内容 我的意思是 如果服务
  • Linux TUN/TAP:无法从 TAP 设备读回数据

    问题是关于如何正确配置想要使用 Tun Tap 模块的 Linux 主机 My Goal 利用现有的路由软件 以下为APP1和APP2 但拦截并修改其发送和接收的所有消息 由Mediator完成 我的场景 Ubuntu 10 04 Mach

随机推荐

  • 对于 TBitmap,FMX 中是否有相当于 FloodFill 的功能?

    我正在从 VCL 转换为 FMX 在VCL中 TBitmap的TCanvas中有一个名为FloodFill的函数 它允许TBitmap的画布充满特定的颜色 直到在位图的画布上达到另一种特定的颜色 FMX 中有与此功能等效的函数吗 根据 RR
  • 如何列出相机可用的视频分辨率

    如果我的电脑上连接了多个摄像头 我想知道特定摄像头的最佳可用分辨率 例如 有些相机是高清或全高清 1 280 720像素 720p 或1920x1080像素 1080i 1080p 或者最常见的是网络相机 我想至少知道相机正常工作的最佳视频
  • Sitecore 页面编辑器 发布与内容相关的项目

    我有一个 产品页面 产品页面映射到 ProductPage Sitecore 项目 网站 页面 产品页面 我在该页面中有一个带有页面编辑器的文本区域 该区域从 Web 数据库中的 产品示例文本 Sitecore 项目的 描述 文本加载文本
  • 有没有办法用 Laravel 的 ELOQUENT ORM 来“限制”结果?

    有没有办法用 Laravel 的 ELOQUENT ORM 来 限制 结果 SELECT FROM games LIMIT 30 30 和雄辩 创建一个扩展 Eloquent 的 Game 模型并使用它 Game take 30 gt sk
  • 如何使用 Javascript WebCrypto API 加载 PKCS#12 数字证书

    我正在尝试使用 WebCrypto API 签署数据 但我真的很想使用用户的 PKCS 12 来签署数据 而不是创建私钥 公钥并将其导出到 pkcs 1 或 8 我已经阅读了 W3C 规范 但无法充分理解它 也找不到任何关于如何执行此操作的
  • 模拟实例属性

    请帮助我理解为什么以下不起作用 特别是 被测试类的实例属性对 Python 不可见unittest Mock 在下面的例子中bar实例属性不可访问 返回的错误是 AttributeError
  • Struts 2 选择带有数组列表值的标签

    我正在开发一个简单的 struts 应用程序 在我的 JSP 中 我有一个下拉列表框 使用s select标签 我需要用操作类中的数组列表值填充这些值 我怎样才能做到这一点 需要进行哪些改变structs xml文件来完成这个 JSP
  • 在WAMP中更改MySQL root密码后无法连接

    这是 WAMPSERVER 中最常见的问题之一 我也遇到了这个问题 并在此处以同一标题发布了我的解决方案 但在没有得到适当的回复 解决方案后 我不得不转储 Wampserver 并安装 XAMPP 运行顺利 为了解决问题Scroll dow
  • 应用重力的宝石镶嵌位板

    我正在尝试用位板制作一个宝石迷阵级联模拟器 到目前为止 我已经能够检测并移除火柴 但现在我需要让珠宝掉下来 我的状态由一系列位板表示 每个位板对应一种宝石 我有一张所有被移除的珠宝的面具 是否可以使用一些按位魔法来做到这一点 两个初始位板的
  • aws 负载均衡器未向实例注册

    I use kubeadm启动集群AWS 我可以成功创建负载均衡器AWS通过使用kubectl 但负载均衡器未向任何 EC2 实例注册 这会导致公共无法访问该服务的问题 从观察来看 ELB创建时 在所有子网下都找不到健康的实例 我很确定我正
  • 如何衡量用户桌面应用程序的使用情况? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我用 c NET 3 5 编写了一个
  • 新的核心数据实体与现有核心数据实体相同:单独的实体还是其他解决方案?

    概述 我正在设计一个餐厅管理应用程序 并且有一个名为 Order 的实体 其中包含 Items 由于一家餐厅可以运营多年 拥有数千个已完成的 订单 并且为了使我的应用程序的网络方面更容易并保持数据库快速运行 我想引入 ClosedOrder
  • 将 pcm 加载到 AVAudioPCMBuffer 中

    我有这个代码 func loadSoundfont pitch String let path String Bundle main path forResource self id pitch ofType f32 let url URL
  • MUI TextField sx props 不应用样式

    我正在尝试使用一次性方式设置 TextField 组件的样式sx prop
  • 启动时结构崩溃

    我的应用程序在 onCreate 函数内的这一行崩溃了 Fabric with this new Crashlytics 该设备是 SAMSUNG SM G313 HZ 运行 4 4 2 我已向他们的 Twitter 开发论坛举报 但我的帖
  • 为什么 Microsoft Word 2007 中的 VBA IDE 智能感知不断更改特定变量类型名称的大小写?

    这是我问过的最奇怪的问题 我什至不知道如何表达它 我记得类似的事情早在 VB6 IDE 中就发生过 但我忘记了修复方法 如果是这种情况 那么这就是 VB IDE 中的一个非常古老的错误 问题是这样的 当我不小心输入时 我正在编写一个简单的
  • 用于时间跟踪的 MongoDB 架构设计

    我创建了一个简单的时间跟踪应用程序 人们可以在其中计时 超时并标记休息时间 此跟踪的中心对象是Event产生于User 这与用户状态确保状态管理正确 这是减去的架构更新时间 创建于 fields userId type mongoose S
  • 实体框架在更新实体时表示属性为空

    我正在尝试将新实体添加到现有集合中 但是 当这样做时 父 实体抱怨其他导航属性为空 尽管它们不是 Error 类型异常 发生 System Data Entity Validation DbEntityValidationException
  • 使用自组织映射进行降维

    过去几个月我一直在研究自组织映射 SOM 但是我在理解降维部分仍然有些困惑 你能建议任何简单的方法来理解 SOM 在任何现实世界数据集上的实际工作吗 就像来自 UCI 存储库的数据集 好的 首先参考一些之前的相关问题 这将使您更好地理解 S
  • 如何将 AnyEvent::Handler 与具有端口重用的套接字一起使用

    最近我遇到了一个很棒的 Perl 模块 AnyEvent 它允许用户进行异步 事件驱动的编程 创建了以下代码片段 效果很好 我遇到的问题是 在打开和关闭大量套接字后 它很快耗尽了所有客户端端口 netstat ant 显示 20 000 多