No, this is a misunderstanding. On the server side, the socket listening on a particular port, can accept multiple connections.
What you cannot do, is to have another socket listening on the same port. (Even this is not quite right, but I don't want to make things too complex, by involving address and port reuse...)
I attached a piece of demo, not a telnet server, but it provides all the basic technics that you are looking for:
proxy.pl:
use strict;
use threads;
use IO::Socket::INET;
$| ++;
my $listener = IO::Socket::INET->new(LocalPort => 3126,
Listen => 5,
Reuse => 1) ||
die "Cannot create socket\n";
my $client;
my $client_num = 0;
while (1) {
$client = $listener->accept;
threads->create(\&start_thread, $client, ++ $client_num);
}
sub start_thread {
threads->self->detach();
my ($client, $client_num) = @_;
print "thread created for client $client_num\n";
while (1) {
my $whole_req = "";
do {
my $req;
$client->recv($req, 700000);
return if ($req eq "");
$whole_req = $whole_req . $req;
} until ($whole_req =~ m/\r\n\r\n/x);
print "client $client_num got req:\n$whole_req";
$whole_req =~ m/Host: ([\.|\w]*)/;
my $host = $1;
my $server = new IO::Socket::INET(Proto => "tcp",
PeerPort => 80,
PeerAddr => $host) ||
die "failed to connect to $host\n";
print $server $whole_req;
my $whole_res = "";
do {
my $res;
$server->recv($res, 700000);
$whole_res = $whole_res . $res;
} until ($whole_res =~ m/<\/html>/);
print "client $client_num got res\n";
print $client $whole_res;
close($server);
}
return;
}
tester.pl:
use strict;
use IO::Socket;
my $server = IO::Socket::INET->new(Proto => "tcp",
PeerPort => 3126,
PeerAddr => "localhost",
Timeout => 2000)
|| die "failed to connect\n";
my $req = "GET / HTTP/1.1\r\nHost: $ARGV[0]\r\n\r\n";
while (1) {
print $req;
print $server $req;
my $res;
my $whole_res = "";
do {
$server->recv($res, 70000);
exit if ($res eq "");
$whole_res = $whole_res . $res;
} until ($res =~ m/<\/html>/);
print $whole_res;
}
| [reply] [d/l] |
| [reply] |
well, you'd need to have a main loop using the listen function to accept incoming connections on port 23. when a connection is accepted, you'd fork into a child and a parent. the parent would continue to listen or new connections and the child would then handle all commands from the newly-connected client.
writing a full-fledged telnet server could be a difficult thing to do. keep in mind that there are many freeware telnet servers that may do exactly what you need. | [reply] |
why not use inetd or xinetd? they handle the sockets, sessions, concurrent connections, and host security parts pretty well...
| [reply] [d/l] [select] |
| [reply] |
A quick question:
Why use Expect.pm, when you can use Net::Telnet? Could you provide some sort of cursory explenation about why Expect programming would be better for this cause?
Gyan Kapur
gyan.kapur@rhhllp.com
| [reply] |
| [reply] |
| [reply] |
I've just put together a system like this to automate some tests. However, I didn't write my own telnet server. Since the machines we were running were NT, I wasn't able to find a free telnet server, so I just tried out a evaluation copy of one. *if anyone knows of a free nt telnet server, please share, that would be nice to know*
If I did it again, I'd just write a simple server listening for particular commands and run my tests that way. The telnet road works, but its not at nice as I'd like. If you don't need to, I'd just write a simple listener/talker system.
But then again, maybe you need telnet in particular. In that case, the other's comments are on the money. Don't forget to read the telnet spec. | [reply] |