in reply to Thread weirdness

It almost sounds like your client is waiting for something to be sent from the other end, and the other end dosn't know if it's in send or recv mode, until it receives something. Try experimenting/forcing it with something that forces you into recv mode. One of the problems with using sockets to access a webserver is getting the send/recv right. Maybe the webserver is waiting for you to close your send connection before it returns the page. In typical sockets, you would want to have a forked client that has one branch always in recv mode listening, while the other branch is for sending. Try something like this to tell the web server you are done sending.
$client->send("\r\n"); while (1) { my $msg; if($client->connected){ $client->recv( $msg, 1024 ); print "$msg\n" } # do closing up here, a webserver won't keep an open socket for you # each connection is new }

I'm not really a human, but I play one on earth Remember How Lucky You Are

Replies are listed 'Best First'.
Re^2: Thread weirdness
by Anonymous Monk on Sep 25, 2008 at 10:57 UTC
    It's an IRC server not a web server. The thread function is not doing any recving.
      t's an IRC server not a web server.

      In your original node you identified the problem as: One of the functions connects to a web page and parses the content

      So it dosn't matter if you are an IRC bot, it is still trying to access a web server thru a socket, so you need to deal with the http protocols. This is the most basic ....notice you need to send a Get, or at least a "\n\n", before the web server will respond.

      #!/usr/bin/perl -w # Usage: this_script 192.168.0.1 /~zentara/index.html use IO::Socket; unless (@ARGV > 1) { die "usage: $0 host document ..." } $host = shift(@ARGV); foreach $document ( @ARGV ) { $remote = IO::Socket::INET->new( Proto => "tcp", PeerAddr => $host, PeerPort => "http(80)", ); unless ($remote) { die "cannot connect to http daemon on $host" } $remote->autoflush(1); print $remote "GET $document HTTP/1.0\n\n"; while ( <$remote> ) { print } close $remote; }

      I'm not really a human, but I play one on earth Remember How Lucky You Are
        Here is what an example session looks like:
        * botbot (Botty@rox-AFBE0982) has joined #wtf
        Right now I private message it to login:
        <me> .login 123456 <botbot> Password correct, logged in
        Now I go back to the channel:
        <me> .web http://www.google.com <botbot> WEB FUNCTION THREAD STARTED
        I wait about five seconds for it to send the title of google.com back to me, it doesn't send so i just send some random text.
        <me> ZZZZZZZZZZZZZZZZZZZZ <botbot> Got title: Google <botbot> WEB FUNCTION THREAD FINISHED
        Here's the full bot
        #!/usr/bin/perl use strict; use threads; use IO::Socket::INET; use LWP::UserAgent; my $ua = LWP::UserAgent->new(agent => 'Mozilla/5.0 (Windows; U; Window +s NT 5.1; en-US; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.5'); push @{$ua->requests_redirectable}, "POST"; my($Sock,$Line,$Nick); my(@IRCUnparsed,@IRCParsed); my(%BossUsers); ############################################ my $Server = $ARGV[0] || "127.0.0.1"; my $Channel = $ARGV[1] || qw(#wtf); my $Port = $ARGV[2] || qw(6667); my $NickName = "botbot"; my $Password = qw(123456); ############################################ $Sock = new IO::Socket::INET(PeerAddr=>"$Server:$Port",Proto=>"tcp"); $Sock->autoflush(); die("Couldn't connect: $!\n") unless $Sock; &SendNick(); &send_raw("USER Botty Bot Bott :Bot bot"); while(1){ $Line = <$Sock>; if(!$Sock){print("[-] Sock died\n");exit(0);} @IRCUnparsed = split(/\r\n/,&tchomp($Line)); @IRCParsed = split(/ /,$IRCUnparsed[0]); print($IRCUnparsed[0] . "\n"); if($IRCParsed[0] eq 'PING'){ &send_raw("PONG " . $IRCParsed[1]); } elsif($IRCParsed[1] eq '001'){ &JoinChan; } elsif(($IRCParsed[1] eq '433') || ($IRCParsed[1] eq "436")){ #&SendNick(); #&JoinChan(); } elsif($IRCParsed[1] eq '475'){ &send_raw("QUIT"); } elsif($IRCParsed[1] eq 'KICK'){ &JoinChan; } if(($IRCUnparsed[0] =~ m/^:(.+)!(.+)\@(.+) PRIVMSG (.+) :(.+)/) || + ($IRCUnparsed[0] =~ m/^:(.+)!~(.+)\@(.+) PRIVMSG (.+) :/)){ my($uNick,$uID,$uHost) = ($1,$2,$3); if($5 =~ m/quit/){ &send_raw("QUIT"); die(); } if($4 eq $Channel){ if($IRCParsed[3] eq ':.web'){ my $URL = $IRCParsed[4]; my $Thr = threads->new(\&Web,$URL); } #chan messages } elsif($4 eq $Nick){ #private messages if($BossUsers{$uNick} == 0){ for(0..@IRCParsed){ #print($_ . " -> " . $IRCParsed[$_] . "\n"); } if($IRCParsed[3] eq ':.login'){ if($IRCParsed[4] eq $Password){ &send_msg($uNick,"Password correct, logged in" +); $BossUsers{$uNick} = 1; } else{ &send_msg($uNick,"Password incorrect"); $BossUsers{$uNick} = 0; } } } elsif($BossUsers{$uNick} => 1){ if($IRCParsed[3] eq ':.logout'){ $BossUsers{$uNick} = 0; &send_msg($uNick,"Logged out"); } elsif($IRCParsed[3] eq ":.quit"){ &SendQuit(); } } } $IRCParsed[0] = $1; } } sub Web($) { &send_msg($Channel,"WEB FUNCTION THREAD STARTED"); my($URL,$Request,$Requested,$Content) = @_; $Request = HTTP::Request->new(GET => $URL); $Requested = $ua->request($Request); if($Requested->is_success){ $Content = $Requested->content; if($Content =~ m/<title>(.+)<\/title>/){ &send_msg($Channel,"Got title: $1"); } else{ &send_msg($Channel,"Didn't get title"); } } else{ print "\n[-] Connection error - " . $Requested->status_line . +"\n"; } &send_msg($Channel,"WEB FUNCTION THREAD FINISHED"); } sub SendQuit() { &send_raw("QUIT"); } sub JoinChan() { &send_raw("JOIN " . $Channel); } sub SendNick() { #$Nick = &randnick($NickPrefix); $Nick = $NickName; &send_raw("NICK " . $Nick); } sub randnick($){ return $_[0] . int(rand(1)*100) . int(rand(1)*200) . int(rand(1)*3 +00); } sub send_raw($){ print "[+] $_[0]\n"; print $Sock "$_[0]\r\n"; } sub send_msg($$){ print "[+] PRIVMSG $_[0] :$_[1]\n"; print $Sock "PRIVMSG $_[0] :$_[1]\r\n"; } sub tchomp { my $text = shift; $text =~ s/^(.*?)(?:\x0D\x0A|\x0A|\x0D|\x0C|\x{2028}|\x{2029})/$1/ +s; return $text; } sub urlencode($){ my $unclean = shift; $unclean =~ s/\?/\%3f/gi; $unclean =~ s/ /\+/gi; $unclean =~ s/:/\%3A/gi; $unclean =~ s/\//\%2F/gi; $unclean =~ s/&/\%26/gi; $unclean =~ s/\"/\%22/gi; $unclean =~ s/\'/\%27/gi; $unclean =~ s/,/\%2C/gi; $unclean =~ s/\\/\%5C/gi; return $unclean; } sub urldecode($){ my $clean = shift; $clean =~ s/\%3f/\?/gi; $clean =~ s/\+/ /gi; $clean =~ s/\%3A/:/gi; $clean =~ s/\%2F/\//gi; $clean =~ s/\%26/&/gi; $clean =~ s/\%22/\"/gi; $clean =~ s/\%27/\'/gi; $clean =~ s/\%2C/,/gi; $clean =~ s/\%5C/\\/gi; return $clean; }