HFX Forum

Programming => PERL => Topic started by: benthehutt on February 16, 2006, 10:22:02 AM

Title: Sockets
Post by: benthehutt on February 16, 2006, 10:22:02 AM
I've got a humdinger of a question about Perl.  I've been using Perl for a few weeks now, and I just started into sockets and all the fun stuff that comes with that.  So here's the problem.  I have a script running on a system on the network that creates a socket on some random port like this:

Code (perl) Select

#!/usr/bin/perl -w

#For myComputer

use IO::Socket;
my $localhost = 'myComputer';
my $localport = 6703;
my $protocol = 'tcp';

my $socket = new IO::Socket::INET(LocalHost=>$localhost,
                           LocalPort=>$localport,
                           Proto=>$protocol,
                           Listen=>1,
                           Reuse=>1
                           );
&Failed unless $socket;

my $new_sock = $socket->accept();
while(defined(<$new_sock>)) {
   print $_;
}
close($socket);


close($socket);

sub Failed{
   print "\nSocket connection failed--could not create:\n";
   print "$protocol port on $localhost at $localport\n\n";
}


So when I start up this script it does its business then waits for something to connect to it so it can accept the connection and print whatever input it gives the script.

So then I wrote another script to connect to it locally or remotely and give it something to print out:

Code (perl) Select

#!/usr/bin/perl -w

use IO::Socket;

my $host = 'myComputer';
my $port = 6703;
my $protocol = 'tcp';

my $socket = new IO::Socket::INET   (
                           PeerAddr=>$host,
                           PeerPort=>$port,
                           Proto=>$protocol
                           );
&Failed unless $socket;

print $socket "Hellooo!\n";
close($socket);


sub Failed{
   print "\nSocket connection failed--could not create:\n";
   print "$protocol port on $host at $port\n\n";
}


Then the script just prints and closes the socket.  But whenever I run them together, starting the first one first, then the second, it says:

"Use of uninitialized value in print at sockets.pl line 20, <GEN1> line 1."

and quits.  So how do I manipulate input into the socket and why is this screwing up?  The second script executes fine--I think...

Anyway, any help would be appreciated on the subject.
Title: Re:Sockets
Post by: Metgod on February 17, 2006, 12:03:27 PM
Never did like perl... powerful language though.

Anyway, a bit of research and experimenting solved it:

Try changing the problematic part (line 20) to something like:


my $new_sock = $socket->accept();
while(defined($line = <$new_sock>)) {
  print $line;
}


Should then work ... or it did on my tests anyway. But don't sak me details cause I know crap all about perl ...


Title: Re:Sockets
Post by: benthehutt on February 17, 2006, 01:13:44 PM
You don't like Perl?  Aw, too bad--it's powerful stuff, though, I suppose you know C.  Anyway, that's a good idea, I'll try it this afternoon when I'm back in the office.  I suppose it was stupid of me to try and print a string when it wasn't defined.

Also, do you have any idea why you put <>'s around input in Perl?  I've heard C is similar--though I don't actually know C.

By the way, where did you do your "research?" I could swear I looked everywhere for a stupid answer.
Title: Re:Sockets
Post by: Metgod on February 17, 2006, 01:28:35 PM
Well, I don't like perl in that it's a messy language (looks) IMO. Same with Java btw. I like readability and other things similar to that more than efficiency (usually anyway -- there are some times I feel different though). I know others agree there, but yes it is powerful and quite useful none the less.

Of course, yes, C is too (especially for system programming). As is Python (which I don't know but tempted to). I'm actually (gasp) tempted to learn C++. I really should learn sed (other than the -i option) and awk too. Anyway...

No idea about the < and >. Could probably find out by doing a bit of googling though. And I can't honestly think of anything similar in C (mostly because I don't know what the idea is in perl) and maybe the fact I am a bit off lately.

I have another friend that does perl, and he once suggested 'perldoc'. Check 'man perldoc' for more info. One example is 'perldoc -f <function_name>'. You can also use, e.g., 'perldoc IO::Socket'.

Quite useful information.

Where I did my research....

I went to perl.com, and they have a section on IPC (which is interprocess communication and sockets are an example). Then saw the specific idea on that page:

http://search.cpan.org/dist/perl/pod/perlipc.pod

And then I tested and it worked.

Hope that helps...
Title: Re:Sockets
Post by: benthehutt on February 20, 2006, 07:34:04 PM
I agree with you on the whole ugly thing.  If you like pretty, why don't you learn C++, it's real perdy!  Well, I like it at least.  Though I'm really only comparing it to Perl and ADA and a handful of other butt-ugly languages (save Q-Basic).
As far as the <> question, it really doesn't matter--I just don't understand it.  Take the following code for example:


#!/usr/bin/perl -w

open(INFILE, "fileName.txt");
my @data = <INFILE>;


Whereas, if you assign a variable a value in any other way, there's no <>'s.  I was just wondering if you knew persay, but it doesn't really matter.  I'll be back with more questions later...right now I'm trying to learn how to reverse engineer web-APIs...
Title: Re:Sockets
Post by: benthehutt on February 21, 2006, 10:03:06 AM
Woo-hoo!  I finally got to test out that socket thing--and it totally worked.  Thanks Metty.  Now to do something useful with it... ;D
Title: Re:Sockets
Post by: benthehutt on February 22, 2006, 04:42:26 PM
So this is my idea:  chatroom.  I mean, not for actual application--just to figure out new things to do with Perl and sockets.  My idea is to have a script that creates a new socket.  Then a generic script that connects to that socket from wherever the heck you want to be.  Then as many scripts can run from wherever--since the one script will be written generally...it's an idea anyway.  I'll write a "prototype" first...
Title: Re:Sockets
Post by: benthehutt on February 23, 2006, 04:19:33 PM
Attempt 1:  One-Way Communication

My first attempt is first of all a failure, but still very enlightening. First, I took the dual script approach where one script fools with creating and binding the socket, and the second one connects and talks to it.  Here's the script that creates the socket, you also specify the host and port:

Code (perl) Select

#!/usr/bin/perl -w

use IO::Socket::INET;

#Sees if you entered the correct command line arguments
unless (scalar(@ARGV) == 2){print "\nUsage:  perl $0 [host] [port]\n";exit;}
my ($host, $port) = @ARGV;

#Creates a new socket and calls failed() if it couldn't make one
my $socket = new IO::Socket::INET(   Proto=>'tcp',
                           LocalHost=>$host,
                           LocalPort=>$port,
                           Listen=>1,
                           Reuse=>1) || &Failed;

print "\nListening on $host:$port for users...\n";

#Accept incoming connections
my $listen = $socket->accept();

#Call recursive subprogram--this is kinda dirty, but it's only a "first draft"
&hear;

sub hear{
#Here's the part with the problem.  This command will block everything
#else until it gets something, then it prints
   while(defined ($line = <$listen>)) {
      print $line;
#If you type in "q" the script exits
      if ($line=~/\bq\b/){close($socket);exit;}
   }
#Recursive call
   &hear;
}

sub Failed{
   print "\nSocket connection failed--could not create:\n";
   print "TCP port at $host:$port\n\n";
   exit;
}


Now then, the problem with this, as labeled in my comments, is that the script blocks everything until it gets input, then it prints.  But I'll come back to this later.  The script that connects to this socket follows:



Code (perl) Select

#!/usr/bin/perl -w

use IO::Socket;

unless (scalar(@ARGV) == 2){print "\nUsage:  perl $0 [host] [port]\n";exit;}
my ($host, $port) = @ARGV;

my $socket = new IO::Socket::INET   (
                           PeerAddr=>$host,
                           PeerPort=>$port,
                           Proto=>'tcp'
                           );

&Failed unless $socket;

#Another dirty recurive subprogram
&print;

sub print{
#Get some input...
   $line = <STDIN>;
#Print it to the socket
   print $socket $line;
#Quit if you type "q"
   if($line=~/\bq\b/){
      $socket->autoflush(1);
      close($socket);
      exit;
   }
#Recursive call
   &print;
}

sub Failed{
   print "\nSocket connection failed--could not connect to:\n";
   print "Could not connect to $host:$port\n";
   exit;
}


Here again the program blocks until something is typed in...But it works nicely if you want to creep someone out "Matrix-style" with words being typed on their screen--but not much for anything else.

So I'm currently researching a few alternatives.  The first is to use Perl's select() command to tell me what's waiting and then execute code based on that.  The second option is to use fork or some other means to manipulate two distinct threads at once.  Then one could be watching things coming in from the socket, the other could be watching things coming in from the keyboard.

So concludes my failed attempt number 1.  I'll be back with results--hopefully...

And if anyone has any suggestions, please speak up!  I've never done any socket programming so I know I'm doing this a stupid way.  But then again--that's how you learn. ;D
Title: Re:Sockets
Post by: Metgod on February 23, 2006, 08:57:27 PM
Various techniques, yeah.

Select is a nice way.... I'd actually recommend you to check out these two documents for a nice overview. It's for C but the idea is the same I'd think.

http://beej.us/guide/bgnet/

http://beej.us/guide/ipc/

There is also a BSD socket guide out there. The above ones I think are HP-UX (been a while since I last checked it).

It's a damn shame but I actually started a decent guide on raw sockets but never got to finishing it and it's since lost (much like all my other would be documents). Anyway... if this doesn't help let me know and I'll try to be of more help.

But back to my slumber of sorts for now ...

Title: Re:Sockets
Post by: Metgod on February 23, 2006, 10:55:52 PM
btw, might want to check these too:

http://www.erlenstar.demon.co.uk/unix/faq_toc.html

http://www.linuxprofilm.com/articles/linux-daemon-howto.html

The latter is probably more useful for you... since it's relavent to your problem. I know there is another set of documents.. trying to remember where.. will post back if I can find it.

I kind of miss this stuff.. might have to get back in to it soon. I wonder if I'll make it a year though (or even a month, haha)
Title: Re:Sockets
Post by: Metgod on February 23, 2006, 11:03:09 PM
Ah, yes... ibm.com is _loaded_ with programming information.

http://www-128.ibm.com/developerworks/linux/library/l-sprace.html?ca=dgr-lnxw06RACE
http://www-128.ibm.com/developerworks/linux/library/l-recurs.html
http://www-128.ibm.com/developerworks/linux/library/l-reent.html
http://www-128.ibm.com/developerworks/linux/library/l-shlibs.html

and much much more! The only problem is something I think zerored has as his sig... (that or godaigo.. sorry, can't really remember) so much to learn, so little time... Words of the wise for sure.

Edit:

bloody bbs... killing the link. Anyway, just check that site out and the directory .. since it has lots of info.


Title: Re:Sockets
Post by: Metgod on February 23, 2006, 11:38:32 PM
Oh and one more thing that might be of use ...

Large programs are a great way to learn how to code! Some might scoff and say you have to know a language to actually gain a lot and do well on modifying big programs, but that's complete and utter nonsense....

Learning by example is very productive ... and if you have the motivation (and enjoy whatever it may be [for me it's muds]), you'll find you learn a lot (mostly since it's easier to work on something you enjoy). Could be through the original coder's mistakes/bugs, or even non-bugs. Also goofing around with it and changing things to your liking. Even fixing your own mistakes is useful. Can get ideas from it and then write test programs (and check it out with debuggers) and so on.

CVS (or any revision control system) is quite useful as well (since you can keep a whole record of your own stupidity [which happens to me a lot, haha] and also brilliance... and then you can simply revert back to a working copy if you screw up too badly). Over time it'll be worth it ...


Ok.. enough rambling from me. Hope this of use to someone :)

Title: Re:Sockets
Post by: benthehutt on February 25, 2006, 12:26:52 PM
Wow, this outta keep me busy *forever*.  Thanks for the help metty, I probably won't be able to work on this stuff until at least Monday, but thanks nonetheless. ;D
Title: Re:Sockets
Post by: Metgod on February 27, 2006, 11:07:47 AM
Glad to be of help. I once upon a time refused to register at ibm (it's free but I hate registering), but the other day I did and it was well worth it.

And by the by I found this:

man 2 select_tut

which should work on any linux box. For C again but it'll give you a nice overview.