http://qs1969.pair.com?node_id=484849

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

How to make such a socket?:)
I understood that there are 2 ways:
using IO::Socket
using Fcntl ?
I'm sort of familiar with IO::Socket, and I write simple IRC bots/servers. I thought that:
$sock->autoflush(1); $| = 1;
makes the socket non-blocking, but a friend of mine just laughed and said that I'm wrong :) He said that I better use Fcntl, but it still could be done with IO::Socket... I'm confused.
Let's say according to me, a non-blocking socket allows other parts of the code to be executed in the same time where the socket is being read or wrote. This is how I do with IO::Socket:
IO::Socket -> create the socket $sock->autoflush(1); $| = 1; while (<$sock> ){ if ($sock =~ /some stuff/){ do(some other stuff); } }
So in that way I make simple query-response bots, but nothing more than that.
I want to make simple application: a timer bot. Let's say at every 30 seconds, it writes a line to the socked, and uses time() function. I don't know even where from to start. Somebody give me a direction please?

Replies are listed 'Best First'.
Re: About non-blocking sockets
by Transient (Hermit) on Aug 18, 2005 at 16:23 UTC
    see IO::Handle's blocking call (parent of IO::Socket)
      So if $conn is my socket handler, returned from the new() method of IO::Socket, I should try that?
      $conn->blocking(0);
      What is the difference between ->blocking and ->autoflush?
      After ->blocking(0) how could I work with that socket?
      If you can give me a short example, I would be very gratefull :)

        Blocking is when an action will stall if it can't be completed immediately.
        An example using a socket would be if you read from it when there is no data to receive my $line = <$soc>; if there is no data the program will electively wait at this bit of code until a full line of data is received then the read operation will return and the program will continue. The waiting is called blocking. It's most often a concern when reading data, but in some circumstances it can happen when writing as well.
        To see blocking in effect try

        print "enter some text and press enter\n"; print "enter quit to exit\n"; while (<>) { chomp; exit if $_ = quit"; print "I got $_\n"; }
        In the above code the readline operator (<>) will block waiting for a line to be typed in on the console. When enter is pressed it will be read in and printed back out, then it will block again at the readline.

        Buffering (controlled by $| or ->autoflush) is when input or output is collected together and stored before it moves from it's source to it's destination.
        It can be though of a bit like a bucket, each time you print a cup of water is poured into the bucket. Because for the computer it takes time to empty the bucket it's only emptied when enough water is poured in to fill it up. However if it is important that the water reach it's destination in a timely fashion you can set the bucket to be emptied after each addition of water.
        To see buffering try

        print "sleeping: "; sleep 2; print "done\n"; sleep 1; $|=1; print "sleeping again: "; sleep 2; print "done\n"
        Under most consoles (but possibly not all) you will see nothing for 2 seconds and then the full line "sleeping: done\n" will be printed out. Then a second later you will see "sleeping again: " printed out with the cursor left at the end of the line. Two seconds later "done\n" is printed. The difference is because most consoles are line buffered by default. That means they wait until they have a full line before they print any thing out. Setting $| to a true value causes this buffer to be flushed after each print statement, letting you see a partial line.

Re: About non-blocking sockets
by johnnywang (Priest) on Aug 18, 2005 at 17:27 UTC
    You should look into POE, it will be only a few lines of code with it.
Re: About non-blocking sockets
by zentara (Archbishop) on Aug 18, 2005 at 20:50 UTC
    If you want to be able to do something else, while the socket receives data, then you have a few alternatives:

    Creating a forking server, but sharing data can be a hassle

    use threads and spawn a thread for each connection which makes sharing data easy

    use POE, which is a commandline event loop system

    use Tk, Gtk2, Wx, etc, which are GUI's which use an event loop

    There are many many examples of all of these on groups.google.com, or in the archived nodes here at perlmonks.

    Now if you get "real creative" in your socket-reading callback, you could use IO::Select to process the sockets, and in the callback for reading, take some time to do another task. But basically IO::Select is used when the socket transfers are small and fast, so the script can process other parts of the loop. So if you are uploading big files, IO::Select will not be a good choice, and you want forks and/or threads or POE, etc.


    I'm not really a human, but I play one on earth. flash japh