Perl not closing TCP sockets if clients are no longer connected? -
the purpose of application listen specific udp multicast , forward data tcp clients connected server. code works fine, have problem sockets not closing after tcp clients disconnects. socketsniffer utility shows the sockets remain open , udp data continues forwarded clients. problem believe "if ($write->connected())" block return true, if tcp client no longer connected. use standard windows telnet connect server , see data. when close telnet, tcp socket suppose close on server.
any reason why connected() show connections active if not? also, alternative should use then?
code:
#!/usr/bin/perl use io::socket::multicast; use io::socket; use io::select; $tcp_port = "4550"; $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'; $udp_socket= io::socket::multicast->new(proto=>'udp',localport=>port); $udp_socket->mcast_add(group) || die "couldn't set group: $!\n"; $read_select = io::select->new(); $write_select = io::select->new(); $read_select->add($tcp_socket); $read_select->add($udp_socket); ## loop forever, reading data udp socket , writing ## tcp socket(s). while (1) { ## no timeout specified (see docs io::select). block until tcp ## client connects or have data. @read = $read_select->can_read(); foreach $read (@read) { if ($read == $tcp_socket) { ## handle connect tcp client. note udp connections ## stateless (no accept necessary)... $new_tcp = $read->accept(); $write_select->add($new_tcp); } elsif ($read == $udp_socket) { ## handle data received udp socket... $recv_buffer; $udp_socket->recv($recv_buffer, 1024, undef); ## write data read udp out tcp client(s). again, no ## timeout. block until tcp socket writable. @write = $write_select->can_write(); foreach $write (@write) { ## make sure socket still connected before writing. if ($write->connected()) { $write->send($recv_buffer); } else { $write_select->remove($write); close $write; } } } } }
i don't know perl, or perl sockets matter, can't think of socket api provides way know if socket connected. in fact, i'm pretty sure tcp doesn't have way of knowing this. suggests me connected() not telling think telling you. (i have no idea, i'll bet telling whether you've called connect/accept or not)
usually sockets tell they've become disconnected reading or writing 0 bytes - might want check return value of write see if ever returns zero
Comments
Post a Comment