I just see that you've gotten an answer in the CB (add my() to the while() loop), but here's a better version of the scipt. Yes, I skip the wait() for waiting on the children. If you add it, the server will quit after the first client disconnects. :) What can I say? I like zombies :P
#!/usr/bin/perl -w
$|++;
use strict;
use IO::Socket;
my $main_sock = new IO::Socket::INET(
LocalHost => '24.71.183.153',
LocalPort => 7800,
Listen => 1,
Proto => 'tcp',
Reuse => 1
) or die "Oops: $!";
while (my $new_sock = $main_sock->accept()) {
if (my $pid = fork()) { # Parent
next;
} elsif (defined $pid) { # Child
print $new_sock 'Hello there, it is now ',
localtime, "\n";
while (defined(
chomp( my $buf = <$new_sock> ) )
) {
print "Client said: $buf\n";
if ($buf =~ /^quit/) {
close $new_sock; last;
}
}
} else {
die "Cannot fork: $!" unless defined($pid);
}
exit(0);
}
exit(0);
If the above content is missing any vital points or you feel that any of the information is misleading, incorrect or irrelevant, please feel free to downvote the post. At the same time, reply to this node or /msg me to tell me what is wrong with the post, so that I may update the node to the best of my ability. If you do not inform me as to why the post deserved a downvote, your vote does not have any significance and will be disregarded.
| [reply] [d/l] |
And what of getting the host or ip of the remote host?
Any help with that? Please?
| [reply] |
| [reply] [d/l] |
I simplified some real code I have, and made it into this demo.
One thing you may notice is that, after fork, as the best practice, in the child process, I close the parent socket; and in the parent process, I close the child socket. The purpose of this is to release resouces, as you don't want to hold anything you don't need.
As jasonk pointed out, you can use peerhost() to get the peer ip addr in xx.xx.xx.xx (ascii) format. His way is very straight forward. Just for the sack of completeness, I provide a different way, by using inet_ntoa($client->peeraddr()). The peeraddr() function returns the peer ip in number format, inet_ntoa is then called to convert number format into ascii format.
server.pl
use IO::Socket;
use strict;
$| ++;
my $server = new IO::Socket::INET(Timeout => 7200,
Proto => "tcp",
LocalPort => 3000,
Reuse => 1,
Listen => 2);
my $num_of_client = -1;
while (1) {
my $client;
do {
$client = $server->accept;
} until (defined($client));
print "new clinet accepted, id = ", ++ $num_of_client,
", peeraddr = ", inet_ntoa($client->peeraddr()),
", peerport = ", $client->peerport(), "\n";
if (!fork) {
close($server);#this only closes the copy in the child process
while (1) {
my $msg;
$client->recv($msg, 1000);
if ($msg eq "") {
die "child $num_of_client is inactive\n";
} else {
print "rcvd $msg from client ", $num_of_client, "\n";
sleep(2);
print $client $msg;
}
}
} else {
close($client); #this only closes the copy in the parent proce
+ss, assume the parent no longer need talk to the client
}
}
client.pl:
use IO::Socket;
use strict;
my $server = new IO::Socket::INET(Proto => "tcp",
PeerAddr => "localhost",
PeerPort => 3000,
Reuse => 1,
Timeout => 7200)
|| die "failed to connect to server\n";
while (1) {
print $server "abcd";
my $msg;
$server->recv($msg, 1000);
if ($msg eq "") {
die "server is not responding";
} else {
print "recv'd ", $msg, "\n";
}
}
| [reply] [d/l] |
All I can say... that code runs 100% like the way you want it to. When I say 'quit' it quits. Immediately. Can you give some specifics as to what version of perl, what operating system you are on, etc etc?
If the above content is missing any vital points or you feel that any of the information is misleading, incorrect or irrelevant, please feel free to downvote the post. At the same time, reply to this node or /msg me to tell me what is wrong with the post, so that I may update the node to the best of my ability. If you do not inform me as to why the post deserved a downvote, your vote does not have any significance and will be disregarded.
| [reply] |
This is perl, v5.6.1 built for i386-linux
| [reply] |