撒哈拉里的鱼
client端使用IO::Select与阻塞问题
以前从来没在客户端使用过IO::Select,今天刚好没事做个测试,结果很迷茫,需要人帮忙解答。判断是否连接成功,是判断can_write,对吧?这个大前提应该没错。我用的perl 5.8.8。首先IO::Socket::INET建立socket,设置为不阻塞,然后下面用select来判断can_write,结果不管什么端口都立即返回为连接成功。只有当socket设置为阻塞的时候,下面用select判断出来的才准确。
这里,刚好和我认为的相反。如果上面socket要阻塞了,下面才能用select判断是否连接成功,似乎有点晕。(当然,我知道select一般是用来轮询socket转发数据之类的)C语言或者C#都可以通过select来判断是否连接成功或者连接断开。perl里面是我做得不对么?
thx!
撒哈拉里的鱼
多谢flw的回答,不好意思,没有把代码贴出来。
[code]
#!/usr/bin/perl
use warnings;
use strict;
use IO::Select;
use IO::Socket::INET;
use Data::Dumper;
my $host = 'www.icylife.net';
my $port = 23456;
my $sock;
$sock = IO::Socket::INET->new( PeerAddr => $host, PeerPort => $port, Proto => 'tcp', Blocking => '0' );
my $select = IO::Select->new( $sock );
my @writes = $select->can_write( 4 );
if( scalar( @writes ) > 0 )
{
print Dumper( @writes );
$sock->close( );
print "Connect to $port ok!/n";
}
else
{
print "Connect to $port timeout!/n";
}
[/code]
撒哈拉里的鱼
恩,这里确实写得不对,原来我下的Network Programming with perl不全。
现在下了完整版的,不过代码还是有问题。
[code]
#!/usr/bin/perl
use IO::Socket;
use Errno qw(EWOULDBLOCK EINPROGRESS);
use IO::Select;
use Data::Dumper;
use warnings;
use strict;
my $host = '124.205.37.93';
my $port = 80;
my $TIMEOUT = 4;
my $sock = IO::Socket::INET->new( Proto => 'tcp', Type => SOCK_STREAM ) or die $@;
$sock->blocking(0); # nonblocking mode
my $addr = sockaddr_in( $port, inet_aton($host) );
my $result = $sock->connect($addr);
unless($result)
{
print Dumper($!);
print Dumper(EINPROGRESS);
die "Can't connect: $!" unless $! != EINPROGRESS;
my $s = IO::Select->new($sock);
die "timeout!" unless $s->can_write($TIMEOUT);
unless ($sock->connected)
{
$! = $sock->sockopt(SO_ERROR);
die "Can't connect: $!"
}
print "Connect ok using non-block!/n";
}
print "Connect ok!/n";
[/code]
按照书上的意思,应该走到unless($result)里面去,但是实际没有……
[[i] 本帖最后由 撒哈拉里的鱼 于 2008-6-30 17:00 编辑 [/i]]