After a long time of testing and retesting and trying to figure out what was wrong with my stupid ftp server (on port 21, hehe) i finally figured out the answer to your problem. It's unbelievably simple too. The most basic rule behind opening socket connections to servers is that you must read input before you send any request to the server. The first mistake in the script is that you forget to read the introduction message from the ftp server before you print that request, since most ftp servers respond to a connection witha simple "welcome" message, while HTTP servers don't. The second mistake here is that when you check for output from the server when there is none, perl waits on the server until it sends a null message or message with data. so if you do:
if (<$sock>) {
print;
}
and the server doesn't have any response to give to you, perl will hang, since it is waiting for the yes or no response from the server. The same goes for while:
while (<$sock>) {
print;
}
it will print the first the introductory lines from the ftp server, but then it will hang waiting to see if the third one exists. thats why when you do:
while (<$sock>) {
print $sock $request;
print;
}
it works on the ftp server because you are constantly giving the server a request to respond to, therefore it will always be responding and perl won't be hanging when it checks the socket. I hope that answers your question, it sure did clear up tons of things for me. when perl does a while loop for input on the http server, the while loop works because an http server closes the connection after one request, so if it checks to see if the socket still exists, perl immediately knows it doesn't since the connection is closed and safely breaks the while loop. With this in mind it probably isn't smart to use a while loop with a server that keeps connections alive until you close them. i made an alternative to your program to work with different types of known servers. check it out:
use strict;
use IO::Socket;
#initial variables to work with my server
my $host, $port, $request, $proto = 'tcp';
my $connectresponses = 2; #my ftp server responds with 2 lines when yo
+u connect.
print "What hostname do you want to connect to? ";
chomp($host = <STDIN>);
print "What port do you want to use? ";
chomp($port = <STDIN>);
my $sock = IO::Socket::INET->new(PeerAddr => $host,
PeerPort => $port,
Proto => $proto) || die "Failure: $!";
print "Connection to $host on port $port successful!\n";
unless ($port == 80) {
for ($i = 0; $i < $connectresponses; $i++) {
$_ = <$sock>;
print;
}
}
print "Type commands (solely press enter to exit)\n";
&Terminal;
close($sock);
print "\nConnection to $host on port $port was closed successfully!\n"
+;
exit;
#sub to emulate a terminal
sub Terminal {
while (1) {
$request = "";
chomp($request = <STDIN>);
print $sock "$request\n";
if ($port == 80) {
while (<$sock>) {
print;
}
last;
} else {
unless ($request) {
last;
}
$_ = <$sock>;
print;
}
}
}
I know it has a few bugs, like when the non-port 80 server reponds with more than one line of response. I got this far, but i am not sure if there is anyway to check how many lines of output the server has to offer.
_____________ALSO______________
These same rules apply for any FILEHANDLE, as i have discovered. So if there is nothing to read, perl will always hang. If there were a way to check that i could make that program so much better, i hear you can use the select function to check what a filehandle has to offer but i haven't figured it out yet. hehe Who needs telnet anyway? heheh. anyways i hope this finally answers your question :)
-rian | [reply] [d/l] [select] |