1

我在eth3:1, eth3:2, eth3:3虚拟机中创建了 3 个不同的虚拟 IP 地址,

现在我正在尝试创建超过 65k 连接到运行在192.168.56.1.

由于VM中的资源是有限的,所以我将端口范围缩小了

sysctl net.ipv4.ip_local_port_range="32768 33000"

然后我尝试创建线程,该线程将使用每个虚拟 IP 地址向 nginx 服务器 ( )600发送请求 ( ) 200 次。GET / HTTP/1.1running at 192.168.56.1

但是我的程序在这里失败了!IO::Socket 告诉我address in use

所以我查看了我的 nginx 日志,它只使用了 2 个不同的 ip 地址(192.168.56.23 and 192.168.56.24)来访问 nginx 服务器,总数只有 233 个(expected 200 x 3 = 600 access logs)。

有谁知道出了什么问题?

#!/usr/bin/perl
use warnings;
use strict;
use threads;
use IO::Socket::INET;

$| = 1;

sub run
{
        my ($ip, $id) = @_;
        print ">> Sendto .. $ip ($id)\n";

        my $socket = new IO::Socket::INET (
                PeerHost  => '192.168.56.1',
                LocalHost => $ip,
                PeerPort  => '80',
                Proto     => 'tcp',
        ) or die $@;

        print $socket "GET / HTTP/1.1\r\n\r\n";
        sleep (100); # hold connection
        $socket->close();
}

my @threads = ();
my @ips = qw/192.168.56.23 192.168.56.24 192.168.56.25/;

foreach my $ip (@ips)
{
        for (1..200)
        {
                push @threads, threads->create (\&run, $ip, $_);
        }
}

$_->join for @threads;
4

1 回答 1

2

Linux 用于查找空闲本地端口的算法并不关心本地 IP 地址,因此端口范围在所有 IP 之间共享。这篇博文进一步讨论了这个问题:http: //aleccolocco.blogspot.com/2008/11/ephemeral-ports-problem-and-solution.html

一种可能的解决方案是手动设置本地端口:

    my $socket = new IO::Socket::INET (
            PeerHost  => '192.168.56.1',
            LocalHost => $ip,
            LocalPort => 32768 + $id,
            PeerPort  => '80',
            Proto     => 'tcp',
    ) or die $@;
于 2013-03-15T08:31:32.007 回答