Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

perl networking problem,no threads used

by spx2 (Deacon)
on Jan 11, 2007 at 09:27 UTC ( [id://594088]=perlquestion: print w/replies, xml ) Need Help??

spx2 has asked for the wisdom of the Perl Monks concerning the following question:

i've read this http://www.perlfect.com/articles/sockets.shtml
and found it to be a very good introduction to network programming in perl
but my problem is that what is there is not enough.
as one can see,it only permits communication in one sense and not the
other.
i've tried to improvise on what i saw there and try to make it the other
way around also.
i've succeded somehow,but it works only for...about 3 seconds and then
i think it stops.
i need help on this,i must say that i have checked a book
Network Programming in Perl and also some other articles and was not
able to found a solution.

Ok,now the code,and afterwards some comments about it.


receiver.pl
use IO::Socket; my $sock = new IO::Socket::INET ( LocalHost => 'localhost', LocalPort => '7070', Proto=>'tcp', Listen=>1, Reuse=>1, ); my $new_sock = $sock->accept(); $i=0; while(1){ print $new_sock "HIII CALLER!\n"; print $new_sock "stop reading ,caller!\n"; while(<$new_sock>){ print $_; if($_ == "stop reading ,receiver!\n"){ last; }; } } close($sock);



caller.pl
use IO::Socket; $sock =0; while(!$sock){ $sock = new IO::Socket::INET ( PeerAddr => 'localhost', PeerPort => '7070', Proto => 'tcp', ); } die "Could not create socket: $!\n" unless $sock; while(1){ print $sock "HIIII RECEIVER!\n"; print $sock "stop reading ,receiver!\n"; while(<$sock>){ print $_; if($_ == "stop reading ,caller!\n"){ last; }; } }; close($sock);


in caller.pl we have the first while wich is waiting for receiver to
create the socket,and when the socket will be created
!$sock will be true thus,it will exit the loop and start
writing to the socket and reading from it.
what it will do ,actually is,it will first write a message to the
receiver,and then write a message that the receiver will interpret
as to stop reading and do something else(receiver will write to
the socket his message).
and so forth,and in the end close the socket.

in receiver.pl we create the socket and we start writing and reading from
it,writing some messages to caller and reading what caller has said,
but also interpret the "stop reading receiver!\n" message wich will
mean the receiver will stop reading and will start writing some messages
to caller,but in turn he will also issue a message to caller for him to stop
reading ,the message for this will be "stop reading caller!\n".


what i want you to know is that i do not intend to say that this code is
very correct or anything ,i just want to make it work properly ,that is all.
if you know of any other methods,please inform me.

thank you

Replies are listed 'Best First'.
Re: perl networking problem,no threads used
by zentara (Archbishop) on Jan 11, 2007 at 12:04 UTC
    it only permits communication in one sense and not the other

    Look at the perldoc for IO::Socket, for the send and recv methods. In a simple single process socket communication scheme, you need to setup a protocol telling the respective sockets when to go into send mode or recv mode. If you don't do this correctly, they will block each other. It's sort of like the old 2-way radio, where you needed to say "over", to signal the other end that you were stopping sending, and going into receive mode.

    Usually a better method is to have forking or threading servers, and clients, that setup 2 socket pairs, one going one way and the other going back. Google for "perl forking chat" , etc.

    But here are is a simple example of an echoing server client pair that goes both ways. It can get more complex where you can have the server accpet input on it's stdin and send to all, or just 1 of the clients. You just need to keep track of the sockets, and which belongs to who.

    ####### SERVER:

    #!/usr/bin/perl use IO::Socket; use IO::Select; my @sockets; my $machine_addr = '192.168.0.9'; $main_sock = new IO::Socket::INET(LocalAddr=>$machine_addr, LocalPort=>1200, Proto=>'tcp', Listen=>3, Reuse=>1, ); die "Could not connect: $!" unless $main_sock; print "Starting Server\n"; $readable_handles = new IO::Select(); $readable_handles->add($main_sock); while (1) { ($new_readable) = IO::Select->select($readable_handles, undef, undef +, 0); foreach $sock (@$new_readable) { if ($sock == $main_sock) { $new_sock = $sock->accept(); $readable_handles->add($new_sock); } else { $buf = <$sock>; if ($buf) { print "$buf\n"; my @sockets = $readable_handles->can_write(); #print $sock "You sent $buf\n"; foreach my $sck(@sockets){print $sck "$buf\n";} } else { $readable_handles->remove($sock); close($sock); } } } } print "Terminating Server\n"; close $main_sock; getc();

    ##### Bi-directional client #######################

    #!/usr/bin/perl -w use strict; use IO::Socket; my ( $host, $port, $kidpid, $handle, $line ); ( $host, $port ) = ('192.168.0.9',1200); my $name = shift || ''; if($name eq ''){print "What's your name?\n"} chomp ($name = <>); # create a tcp connection to the specified host and port $handle = IO::Socket::INET->new( Proto => "tcp", PeerAddr => $host, PeerPort => $port ) or die "can't connect to port $port on $host: $!"; $handle->autoflush(1); # so output gets there right away print STDERR "[Connected to $host:$port]\n"; # split the program into two processes, identical twins die "can't fork: $!" unless defined( $kidpid = fork() ); # the if{} block runs only in the parent process if ($kidpid) { # copy the socket to standard output while ( defined( $line = <$handle> ) ) { print STDOUT $line; } kill( "TERM", $kidpid ); # send SIGTERM to child } # the else{} block runs only in the child process else { # copy standard input to the socket while ( defined( $line = <STDIN> ) ) { print $handle "$name->$line"; } }

    There are numerous examples on groups.google.com, just get out there, and dig them out.


    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
      isnt the documentation supposed to lead a coder so that he can code his own. why is there need to look up examples written by others. everyone here probably has some self-respect
        why is there need to look up examples written by others. everyone here probably has some self-respect

        Well, the perldocs do not always show complete working code examples, especially if you are on windows. Furthermore, you didn't take that example from the perldoc, it was some "perlfect site mini-tutorial". Bi-directional sockets are tricky to make work correctly, and you may as well benefit from other people who have already solved a problem. You almost always need IO::Select with Sockets. The Perlfect tutorial should have mentioned that. If you have "self-respect", don't ask here. :-) Self-respect is another word for "ego", and a good monk is ego-less and humble.


        I'm not really a human, but I play one on earth. Cogito ergo sum a bum
      thank you zentara
      the code you just posted is much more than i want
      but it is very nice and i'll try to study it soon
        Since you seem to be starting to learn Sockets, you may be interested in looking at these nice self-documenting code examples, which don't use high-level modules, that show how sockets really work. UNO Golden Socket examples (Scroll down to Perl ) After a few socket scripts, you will come to appreciate the higher-level-socket modules, but it's also nice to see the real thing.

        I'm not really a human, but I play one on earth. Cogito ergo sum a bum
Re: perl networking problem,no threads used
by shonorio (Hermit) on Jan 11, 2007 at 10:09 UTC
    I not sure if you want a code to learning how to program a server on Perl or to use on a real production environment. Anyway, I recommend you to use Net::Server or POE. They will help you for both, learner and real program.

    More information about POE "A Beginner's Introduction to POE".

    Solli Moreira Honorio
    Sao Paulo - Brazil

Re: perl networking problem,no threads used
by bart (Canon) on Jan 11, 2007 at 11:34 UTC
    You don't say what your platform is. I must say, much of the code in Lincoln Stein's book "Network Programming with Perl" has trouble running well on Windows, while I'm sure it's fine on Linux/*BSD.

    Likewise, POE, as suggested by another user, will likely pose problems on Windows. At least, many of the tests, when installing, simply appear to hang. Use with caution.

      POE works absolutely fine on MSWin32, especially for sockets.

      For ease of installation I provide PAR::Dist installable PAR files of the latest POE at my poco-irc webpage.

        Then, can you explain the hangs when running the tests (from the installation distribution on CPAN) on Win32?

        It's not just for me, and I've tried it on several Perl ports, but Corion has told me the same thing in the Chatterbox.

      I am on windows
        I am on windows
        Aha. That's the root of your problem.

        Unfortunately I still have too little experience in this field to know exactly just what works and what doesn't work. I'm working on it, on and off, I'm still learning this stuff and Windows is a platform I use a lot.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://594088]
Approved by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (8)
As of 2024-04-23 08:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found