Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

socket and thread question 1

Status
Not open for further replies.

majinbis

Programmer
Sep 2, 2009
6
US
I'm really new to socket programming and I have the following code (don't mind the client, still needs to be worked on). I used it as a web proxy for firefox and went to " And while it "worked", my command prompt kept on beeping with garbled characters (i assume from the Google image on the homepage) and it took a good 10 minutes to load the google homepage. then i got stuck and never closed the connection.

Q1: is there a limit to the muber of bytes/chars that can be sent at a time? (that's why my cmd$ kept on beeping when FF was loading the image?)

Q2: why is it taking so long?

Q3: how can I implement using tabs (thread? i read it's slow)

#!c:\bin\perl -w
use IO::Socket;
my $proxy_port=9000;
my $hostname=`hostname`;
chop $hostname;

# socket
$sock = new IO::Socket::INET (LocalHost => $hostname,
LocalPort => $proxy_port,
Proto => 'tcp',
Listen => 5,
Reuse => 1
) || die "Listening Socket could not be created: $!" unless $sock;

while (1) {
# Accept connection request
print "Waiting for connection request....\n\n";
$client_sock = $sock->accept() || die "accept $!";

# Create child process
if (fork) {
wait;
next;
}

$clientaddr = getpeername ($client_sock);
($port,$iaddr) = sockaddr_in($clientaddr);
$clientname = gethostbyaddr ($iaddr, AF_INET);

print "Received Connection Request from: ".inet_ntoa($iaddr)."\n";

$firstline = <$client_sock>;
print "*********** HTTP request ************\n";
print $firstline."\n";
($modifiedfirstline,$remote_host,$remote_port,$method)=analyze($firstline);

$server_sock=connect_server($remote_host,$remote_port);
print $server_sock $firstline;

while (<$client_sock>) {
print $_;
next if (/Proxy-Connection:/);
print $server_sock $_;
last if ($_ =~ /^[\s\x00]*$/);
}

if ($method eq "POST") {
$data = <$client_sock>;
print $data;
print $server_sock $data;
}

print "HTTP Request sent. Here's the response: \n\n";

server_response($server_sock, $client_sock);

close $client_sock;
close $server_sock;
exit;
}


sub analyze {
($request)=@_;
if ($request =~ m#(GET|POST|HEAD) [^/:]+):?(\d*)#) {
$method=$1;
$remote_host=$2;
$remote_port=$3;
print "Recognized HTTP request \n";
}

print "Received $method request for remote_host $remote_host at port

$remote_port...\n";

# Remove remote hostname from URL
$request =~ s/http:\/\/[^\/]+//;
return $request,$remote_host,$remote_port,$method;
}


sub connect_server {
($remote_host,$remote_port) = @_;
if ($remote_port !~ /^\d+$/) {
$remote_port = (getservbyname($remote_port, "tcp"))[2];
$remote_port = 80;
}

$server_sock = new IO::Socket::INET (PeerAddr => $remote_host,
PeerPort => $remote_port,
Proto => 'tcp') || die "Server Socket could not be created: $!";
print "Connected to server $remote_host at port $remote_port";
return $server_sock;
}

sub server_response {
($server_sock, $client_sock) = @_;
while ($line = <$server_sock>) {
print $line;
print $client_sock $line;
}
print "Finished receiving...\n";
}
 
The beeping and garbled characters is a result of your code printing all the http traffic. When an image gets sent over the network and you print it in the terminal, you're printing binary, a lot of which are non-printing characters (hex values below 0x20). Somewhere in that non-printing range is the alarm character (or "\a" if you wanted to make your script beep on purpose), so when this character goes over the terminal, your terminal beeps.

You should probably either: not print all the output, or print it in hexadecimal. Here's a hacked-together function I wrote in a Perl module I was working on that deals with binary, it outputs things in the same format as `hexdump -C` does - showing the hex on the left, then the ASCII equivalent on the right (with non-printing characters displaying as a dot instead):

Code:
sub hexdump {
    my ($line) = @_;

    my @chars = split(//, $line);

    # Show 16 columns in a row.
    my $col = 0;
    my $buffer = '';
    for (my $i = 0; $i < scalar(@chars); $i++) {
        my $char = sprintf("%02x", unpack("C", $chars[$i]));
        my $escaped = unpack("C", $chars[$i]);
        if ($escaped < 20) {
            $escaped = ".";
        }
        else {
            $escaped = chr($escaped);
        }
        $buffer .= $escaped;
        print "$char ";
        $col++;
        if ($col == 8) {
            print "  ";
        }
        if ($col == 16) {
            $buffer .= " " until length $buffer >= 16;
            print "  |$buffer|\n";
            $buffer = '';
            $col = 0;
        }
    }
    while ($col < 16) {
        print "   ";
        $col++;
        if ($col == 8) {
            print "  ";
        }
        if ($col == 16) {
            $buffer .= " " until length $buffer >= 16;
            print "  |$buffer|\n";
            $buffer = '';
        }
    }
    if (length $buffer) {
        print "|$buffer|\n";
    }
}

Call hexdump($data) to display your data instead of printing it directly.

Cuvou.com | My personal homepage
Code:
perl -e '$|=$i=1;print" oo\n<|>\n_|_";x:sleep$|;print"\b",$i++%2?"/":"_";goto x;'
 
Thanks! I removed the code that printed the output to the terminal and it went well. A few more things though:

1. It gets stuck waiting for the host to respond (Google) or I get a Bad Request (Yahoo). Eventually, it'll go though but like after 15-20 minutes...

2. Takes forever to load stuff in HTTP/1.1 but if I try to telnet the proxy, it works fine
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top