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;
}