该应用程序的目的是侦听特定的UDP多播,然后将数据转发到连接到服务器的任何TCP客户端.代码工作正常,但在TCP客户端断开连接后,我的套接字没有关闭.套接字实用程序实用程序显示套接字保持打开状态,并且所有UDP数据继续转发到客户端.我认为问题在于"if($ write-> connected())"块,因为它总是返回true,即使TCP客户端不再连接.我使用标准的Windows Telnet连接到服务器并查看数据.当我关闭telnet时,TCP套接字假设在服务器上关闭.
为什么connected()显示连接是活动的,即使它们不是?另外,我应该使用什么替代品呢?
码:
#!/usr/bin/perl use IO::Socket::Multicast; use IO::Socket; use IO::Select; my $tcp_port = "4550"; my $tcp_socket = IO::Socket::INET->new( Listen => SOMAXCONN, LocalAddr => '0.0.0.0', LocalPort => $tcp_port, Proto => 'tcp', ReuseAddr => 1, ); use Socket qw(IPPROTO_TCP TCP_NODELAY); setsockopt( $tcp_socket, IPPROTO_TCP, TCP_NODELAY, 1); use constant GROUP => '239.2.0.81'; use constant PORT => '6550'; my $udp_socket= IO::Socket::Multicast->new(Proto=>'udp',LocalPort=>PORT); $udp_socket->mcast_add(GROUP) || die "Couldn't set group: $!\n"; my $read_select = IO::Select->new(); my $write_select = IO::Select->new(); $read_select->add($tcp_socket); $read_select->add($udp_socket); ## Loop forever, reading data from the UDP socket and writing it to the ## TCP socket(s). while (1) { ## No timeout specified (see docs for IO::Select). This will block until a TCP ## client connects or we have data. my @read = $read_select->can_read(); foreach my $read (@read) { if ($read == $tcp_socket) { ## Handle connect from TCP client. Note that UDP connections are ## stateless (no accept necessary)... my $new_tcp = $read->accept(); $write_select->add($new_tcp); } elsif ($read == $udp_socket) { ## Handle data received from UDP socket... my $recv_buffer; $udp_socket->recv($recv_buffer, 1024, undef); ## Write the data read from UDP out to the TCP client(s). Again, no ## timeout. This will block until a TCP socket is writable. my @write = $write_select->can_write(); foreach my $write (@write) { ## Make sure the socket is still connected before writing. if ($write->connected()) { $write->send($recv_buffer); } else { $write_select->remove($write); close $write; } } } } }
Stewart.. 5
我对perl或perl套接字一无所知,但我想不出一个套接字API,它提供了一种知道套接字是否连接的方法.事实上,我很确定TCP实际上并没有像这样立即知道的方式.这告诉我,connected()并没有告诉你你认为它告诉你什么.(我不知道,但我敢打赌,它告诉你你是否打电话给连接/接受)
通常套接字通过读取或写入零字节来告诉您它们已断开连接 - 您可能希望检查写入的返回值以查看它是否返回零
我对perl或perl套接字一无所知,但我想不出一个套接字API,它提供了一种知道套接字是否连接的方法.事实上,我很确定TCP实际上并没有像这样立即知道的方式.这告诉我,connected()并没有告诉你你认为它告诉你什么.(我不知道,但我敢打赌,它告诉你你是否打电话给连接/接受)
通常套接字通过读取或写入零字节来告诉您它们已断开连接 - 您可能希望检查写入的返回值以查看它是否返回零