![]() |
IO::Socket Stop listening for new connections after initial connection
Writing a small server where I want the server to stop accepting new
connections after the inital client connects. I'm creating the socket as such: $sock = new IO::Socket::INET( LocalHost => $cip, LocalPort => $cport, Proto => 'tcp', Listen => 0, ReuseAddr => 1, ); ($csock, $c_addr) = $sock->accept(); ($c_port, $c_ip) = sockaddr_in($c_addr); $c_ipnum = inet_ntoa($c_ip); print "Client connecting from: $c_ipnum:$c_port\n"; Once $csock gets defined (client connection), I would like the server to stop listening for new connections. If I use close on the original $sock it closes $csock as well so I'm not quite sure how to go about achieving this. I'm pretty new to socket programming in Perl, so any ideas would be helpful. Thanks! |
Re: IO::Socket Stop listening for new connections after initial connection
sgt_b2002@yahoo.com wrote:
> Writing a small server where I want the server to stop accepting new > connections after the inital client connects. I'm creating the socket > as such: > $sock = new IO::Socket::INET( > LocalHost => $cip, > LocalPort => $cport, > Proto => 'tcp', > Listen => 0, > ReuseAddr => 1, > ); > ($csock, $c_addr) = $sock->accept(); > ($c_port, $c_ip) = sockaddr_in($c_addr); > $c_ipnum = inet_ntoa($c_ip); > print "Client connecting from: $c_ipnum:$c_port\n"; > > Once $csock gets defined (client connection), I would like the server > to stop listening for new connections. If I use close on the original > $sock Your code does not show you using close on the original $sock. > it closes $csock as well so I'm not quite sure how to go about > achieving this. I cannot verify this. I close $sock, and $csock goes merrily on its way, just as I expected it to do. Can you provide a complete, runnable program which reproduces your problem? use IO::Socket::INET; $sock = new IO::Socket::INET( LocalPort => 9999, Listen=> 0, ReuseAddr=> 1, ); ($csock, $c_addr) = $sock->accept(); ($c_port, $c_ip) = sockaddr_in($c_addr); $c_ipnum = inet_ntoa($c_ip); print "Client connecting from: $csock $c_ipnum:$c_port\n"; close $sock or die $!; print while <$csock>; The first "telnet localhost 9999" I run connects, and stays connected for as long as it wants, sending data to the server, which the server echos. Any subsequent "telnet localhost 9999" I try to run gets a connection refused. Xho -- -------------------- http://NewsReader.Com/ -------------------- Usenet Newsgroup Service $9.95/Month 30GB |
Re: IO::Socket Stop listening for new connections after initial connection
Hey Xho, thanks for your reply. Thanks for the code too, nicely
illustrates how you do this. The reason I was having an issue was that a while back when I started this project I asked this question in #perl. Someone there told me that you *cannot* close the "original socket". That kind of confused me as I thought you *should* be able to do this. Thanks for making that clear. After trying this in my code I can see that it works well, although some other issues were created. I wrote a small program to illustrate this issue. It essentially creates a server that listens on two ports. Telnet to both ports and anything typed in one console will be sent through the server and echo'd in the other console. Pretty simple. The script works fine until I try to close the "original sockets". In the code, when $asock is created I close $agent_sock. When $agent_sock is closed, however, $client_sock closes as well. I'm really kind of confused as to why this is happening. If you have the time, maybe you can explain what it is I'm doing wrong. Essentially I want to listen on both ports. When a connection is made on one port, I want to stop listening on that port, but continue to listen on the other port until a connection is created there. Then stop listening that port too. Any advice you can give would be helpful. Uncomment the close statements to see the problem I'm facing. #!/usr/bin/perl use IO::Select; use IO::Socket; while (1) { $sel = IO::Select->new(); unless (defined $asock) { $agent_sock = new IO::Socket::INET( LocalHost => '127.0.0.1', LocalPort => 1234, Proto => 'tcp', Listen => 1, ReuseAddr => 1, ); $sel->add($agent_sock); } unless (defined $csock) { $client_sock = new IO::Socket::INET( LocalHost => '127.0.0.1', LocalPort => 4321, Proto => 'tcp', Listen => 1, ReuseAddr => 1, ); $sel->add($client_sock); } &startserver; } sub startserver { while(@ready = $sel->can_read) { foreach $fh (@ready) { if ($fh == $agent_sock) { ($asock, $a_addr) = $agent_sock->accept(); #close $agent_sock; ($a_port, $a_ip) = sockaddr_in($a_addr); $a_ipnum = inet_ntoa($a_ip); print "Agent connecting from: $a_ipnum:$a_port\n"; $sel->add($asock); } elsif ($fh == $client_sock) { ($csock, $c_addr) = $client_sock->accept(); #close $client_sock; ($c_port, $c_ip) = sockaddr_in($c_addr); $c_ipnum = inet_ntoa($c_ip); print "Client connecting from: $c_ipnum:$c_port\n"; $sel->add($csock); } elsif ($fh == $asock) { $asock->close unless defined ($buf = <$asock>); print $csock $buf if defined $csock; } elsif ($fh == $csock) { $csock->close unless defined ($buf2 = <$csock>); print $asock $buf2 if defined $asock; } } } } |
Re: IO::Socket Stop listening for new connections after initial connection
sgt_b2002@yahoo.com wrote:
> Hey Xho, thanks for your reply. You are welcome. But please quote some context when you post follow-ups. I had to go look up my post on google in order to see what it was I originally suggested! ..... > The > script works fine until I try to close the "original sockets". In the > code, when $asock is created I close $agent_sock. When $agent_sock is > closed, however, $client_sock closes as well. I'm really kind of > confused as to why this is happening. One thing is that you really should use strict; use warnings; and check the success of your system calls. If you did that, I think the problem would have made itself more clear to you. .... > while(@ready = $sel->can_read) { > > foreach $fh (@ready) { > if ($fh == $agent_sock) { > ($asock, $a_addr) = $agent_sock->accept(); > close $agent_sock; Here is the root cause of the problem. You are closing $agent_sock, but then leaving it in the watch list for the IO::Select object. You want to do: $sel->remove($agent_sock); close $agent_sock; (And similar for the $client_sock code.) (and probably the other two handles as well.) Xho -- -------------------- http://NewsReader.Com/ -------------------- Usenet Newsgroup Service $9.95/Month 30GB |
Re: IO::Socket Stop listening for new connections after initial connection
> One thing is that you really should use strict; use warnings; and check
> the success of your system calls. If you did that, I think the problem > would have made itself more clear to you. I'll be doing that from now on. > Here is the root cause of the problem. You are closing $agent_sock, but > then leaving it in the watch list for the IO::Select object. > > You want to do: > > $sel->remove($agent_sock); > close $agent_sock; That did it! Soon as I added the $sel->remove for the two sockets everything worked as it should. I should be able to incorporate this into my project now. I did try this initially, but did the $sel->remove *after* I closed the socket. close $agent_sock; $sel->remove($agent_sock); That caused the test program to break (input would not echo to the other console). I'm guessing using strict, warnings, and checking system call success would tell me why. Placing the $sel-remove *before* I close the socket, as you suggest, works. Thank you so much for your help, I really do appreciate it. :) |
| All times are GMT. The time now is 01:02 PM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.