Sockets

Discussion in 'Perl Misc' started by Monty, May 1, 2007.

  1. Monty

    Monty Guest

    Hope this is the right forum for this...

    I'm trying to learn sockets, and I'm studying some examples given
    vrious places on the web. So far I'm with the explanations, but one
    example leaves me perplexed and I'm hoping some one can shed light on
    it. I'm hoping to write a chat-like client-server program, and I
    found this explanatory code:

    .... create socket as before ...
    11 use IO::Select;
    12 $read_set = new IO::Select(); # create handle set for reading
    13 $read_set->add($s); # add the main socket to the set
    14
    15 while (1) { # forever
    16 # get a set of readable handles (blocks until at least one handle
    is ready)
    17 my ($rh_set) = IO::Select->select($read_set, undef, undef, 0);
    18 # take all readable handles in turn
    19 foreach $rh (@$rh_set) {
    20 # if it is the main socket then we have an incoming connection
    and
    21 # we should accept() it and then add the new socket to the
    $read_set
    22 if ($rh == $s) {
    23 $ns = $rh->accept();
    24 $read_set->add($ns);
    25 }
    26 # otherwise it is an ordinary socket and we should read and
    process the request
    27 else {
    28 $buf = <$rh>;
    29 if($buf) { # we get normal input
    30 # ... process $buf ...
    31 }
    32 else { # the client has closed the socket
    33 # remove the socket from the $read_set and close it
    34 $read_set->remove($rh);
    35 close($rh);
    36 }
    37 }
    38 }
    39 }

    Some of you probably recognize this.

    Regardless of your own opinion of this code, I'm wondering about the
    $read_set and $rh_set variables defined here. Are they, in the perl-
    ative or figurative sense, lists or arrays containing socket or file
    handles? I don't quite follow the perldoc on IO::Select to figure
    this out. Also, can sockets generated this way (using IO::Socket) be
    bidirectional?

    Thanks
    Monty, May 1, 2007
    #1
    1. Advertising

  2. Monty

    Bernard Chan Guest

    Monty wrote:
    >
    > ... create socket as before ...
    > 11 use IO::Select;
    > 12 $read_set = new IO::Select(); # create handle set for reading
    > 13 $read_set->add($s); # add the main socket to the set
    > 14
    > 15 while (1) { # forever
    > 16 # get a set of readable handles (blocks until at least one handle
    > is ready)
    > 17 my ($rh_set) = IO::Select->select($read_set, undef, undef, 0);


    My opinion: I have personally considered can_read() of IO::Select easier to
    use and understand. Any reason to use IO::Select->select() instead?

    > 26 # otherwise it is an ordinary socket and we should read and
    > process the request
    > 27 else {
    > 28 $buf = <$rh>;
    > 29 if($buf) { # we get normal input
    > 30 # ... process $buf ...
    > 31 }


    The code is mixing buffered and non buffered IO. Watch out for surprises due
    to unexpected buffering at the PerlIO layer. If I don't get it wrong (I
    have done some investigation around sockets and IO::Select recently),
    IO::Select works underneath the Perl buffering layer while <> (or
    getline()) works with buffering. So it is possible that multiple lines are
    read physically from the socket in one go and cached in the buffer, so
    IO::Select reports nothing more to read, although you have only read a
    single line from the buffer. I/O may then potentially block. I have an
    experiment recently which cost me a day to figure it out.

    > Also, can sockets generated this way (using IO::Socket) be
    > bidirectional?


    Sure. You can read from and write to the same socket, unless you have called
    shutdown() on it to change its duplex nature.

    --
    Regards,
    Bernard Chan

    --
    Posted via a free Usenet account from http://www.teranews.com
    Bernard Chan, May 1, 2007
    #2
    1. Advertising

  3. On 30 Apr 2007 17:37:44 -0700,
    Monty <> wrote:
    > Hope this is the right forum for this...
    >
    > I'm trying to learn sockets, and I'm studying some examples given
    > vrious places on the web. So far I'm with the explanations, but one
    > example leaves me perplexed and I'm hoping some one can shed light on
    > it. I'm hoping to write a chat-like client-server program, and I
    > found this explanatory code:
    >
    > ... create socket as before ...
    > 11 use IO::Select;
    > 12 $read_set = new IO::Select(); # create handle set for reading


    [snip]

    > 17 my ($rh_set) = IO::Select->select($read_set, undef, undef, 0);
    > 18 # take all readable handles in turn
    > 19 foreach $rh (@$rh_set) {


    [snip]

    > Regardless of your own opinion of this code, I'm wondering about the
    > $read_set and $rh_set variables defined here. Are they, in the perl-
    > ative or figurative sense, lists or arrays containing socket or file
    > handles? I don't quite follow the perldoc on IO::Select to figure
    > this out.


    $read_set is an IO::Select object (see code line 12) and $rh_set is a
    reference to an array of file handles that are ready to read. You use
    $read_set by using the documented interface of IO::Select, and you use
    $read_set by dereferencing it, and doing something with each file
    handle.

    A list, in Perl, is not something you can store in a variable. It's a
    syntactic construct, or a runtime construct, but not a thing you can
    store or manipulate. Also see the question 'What is the difference
    between a list and an array?' in the Perl FAQ, section 4.

    You say 'regardless of your own opinion of this code', but do you really
    believe you can post code and not get comments? :)

    The code you submitted is a bit of an odd circumvention of the neat OO
    interface to select that IO::Select gives you. A better, and more
    elegant example which does almost exactly the same as your code, can be
    found at the end of the IO::Select man page. I'd use that instead as
    your model of how to work with IO::Select, and I'd forget this one.

    > Also, can sockets generated this way (using IO::Socket) be
    > bidirectional?


    I don't see why not.

    Martien
    --
    |
    Martien Verbruggen | I'm just very selective about what I accept
    | as reality - Calvin
    |
    Martien verbruggen, May 1, 2007
    #3
  4. Monty

    Monty Guest

    Ok, having read the IO::Select perldoc, I can make some sense out of
    what it's telling me, and the sample code seems clearer than what I've
    found on the web (you're right Martien: how could I NOT expect
    comments on any code posted :) ). A couple of things still elude me,
    though. If I understand correctly, the sample code in the perldoc
    creates a new socket object with $lsn = IO::Socket::INET(etc...) and
    then a new IO::Select object is created with $sel = IO::Select($lsn).
    With that latter statement, my understanding is that an array-like
    object named $sel is created, and $sel can/will contain file handles
    to communications streams going through the socket object, $lsn.

    Before I go on, am I correct so far?
    Monty, May 1, 2007
    #4
  5. Monty

    Guest

    Monty <> wrote:
    > Ok, having read the IO::Select perldoc, I can make some sense out of
    > what it's telling me, and the sample code seems clearer than what I've
    > found on the web (you're right Martien: how could I NOT expect
    > comments on any code posted :) ). A couple of things still elude me,
    > though. If I understand correctly, the sample code in the perldoc
    > creates a new socket object with $lsn = IO::Socket::INET(etc...) and
    > then a new IO::Select object is created with $sel = IO::Select($lsn).


    Yes. The first creates a socket that listens for incoming connections.
    The second lets you listen for those incoming connections without blocking.

    > With that latter statement, my understanding is that an array-like
    > object named $sel is created,


    I have no idea what *you* consider to be "array-like". $sel is an
    IO::Select object. If IO::Select objects are "array-like" to you, then it
    is array-like. But I suspect you will find it less confusing to just accept
    that IO::Select is what it is, rather than trying to force it into
    classifications like "array-like"

    > and $sel can/will contain file handles
    > to communications streams going through the socket object, $lsn.


    $sel "contains" file handles. Initially, $lsn is the only file handle it
    contains. As the code operates, new file handles (sockets created by
    accepting connections negotiated through $lsn) are added to $sel. These
    new connections, once established, are no longer related to $lsn.

    So "$sel->can_read" is basically saying "Wait either for a new connection
    to be ready to be accepted, or until one of the already accepted
    connections has sent me data"

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
    , May 1, 2007
    #5
  6. Monty

    Monty Guest

    >But I suspect you will find it less confusing to just accept
    > that IO::Select is what it is


    So what is it?
    Monty, May 1, 2007
    #6
  7. Monty

    Guest

    Monty <> wrote:
    > >But I suspect you will find it less confusing to just accept
    > > that IO::Select is what it is

    >
    > So what is it?


    A block-box object which behaves the way its docs says it behaves, mostly.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
    , May 1, 2007
    #7
  8. On 1 May 2007 09:59:06 -0700,
    Monty <> wrote:
    >>But I suspect you will find it less confusing to just accept
    >> that IO::Select is what it is

    >
    > So what is it?


    It is mainly an IO::Select object, i.e. you use it in accordance with
    the IO::Select documentation, generally by calling methods on it.

    It is also a reference blessed into the IO::Select class, but that's
    just the way perl implements OO.

    What it is a reference to (and that may very well be an array, but more
    commonly a hash is used) is not important, unless you have to modify the
    code of IO::Select itself. Actually, I just checked, and IO::Select
    objects are indeed references to arrays, but again, it doesn't matter.

    One of the points of OO classes is to encapsulate and hide the
    implementation from the user of the class. It should never be necessary
    to need to know what exactly underlies the implementation.

    If you want to know, however, a quick look at the code is often the best
    way to find out. I used perldoc -m IO::Select to check.

    Martien
    --
    |
    Martien Verbruggen | Blessed are the Fundamentalists, for they
    | shall inhibit the earth.
    |
    Martien verbruggen, May 1, 2007
    #8
  9. Monty

    Monty Guest

    > Actually, I just checked, and IO::Select
    > objects are indeed references to arrays, but again, it doesn't matter.


    Actually, to me, at this stage of understanding, it kind of does
    matter that it's an array. While it could have been an array, a list,
    or a hash, those structures are at least familiar and I know means
    exist for traipsing through them. So now the statement @ready = $sel-
    >can_read begins to shed light for me.


    > One of the points of OO classes is to encapsulate and hide the
    > implementation from the user of the class. It should never be necessary
    > to need to know what exactly underlies the implementation.


    In practice, I won't need to refresh myself with the underlying
    mechanisms, but they are important to learn from.

    So this is what I've got from all this so far: IO::Select allows me to
    'peruse', if you will, all the connections associated with a port I
    designate in a client-server connection, upon or through which I've
    established a communications socket (bear with me if this is rambling
    a bit). Somewhere in the system, something is keeping track of all
    the connections I establish through that port, and IO::Select helps me
    look at them all.

    How's that so far?
    Monty, May 2, 2007
    #9
  10. On 1 May 2007 17:55:59 -0700,
    Monty <> wrote:
    >> Actually, I just checked, and IO::Select
    >> objects are indeed references to arrays, but again, it doesn't matter.

    >
    > Actually, to me, at this stage of understanding, it kind of does
    > matter that it's an array. While it could have been an array, a list,
    > or a hash, those structures are at least familiar and I know means
    > exist for traipsing through them. So now the statement @ready = $sel-
    >>can_read begins to shed light for me.


    But that doesn't actually have anything to wo with what the IO::Select
    object is. It simply has to do with what the can_read method in the
    IO::Select package returns. It returns a list of file handles ready for
    reading. That list is then stored in the array @ready.

    >> One of the points of OO classes is to encapsulate and hide the
    >> implementation from the user of the class. It should never be necessary
    >> to need to know what exactly underlies the implementation.

    >
    > In practice, I won't need to refresh myself with the underlying
    > mechanisms, but they are important to learn from.


    Learning is good. But you do need to make sure that you're learning the
    right things. Starting with the basics -- and someone else has already
    suggested a list of documents to start with -- is important, before you
    start to read OO module code, which can be, and often is, rather terse
    and sometimes somewhat obscure.

    > So this is what I've got from all this so far: IO::Select allows me to
    > 'peruse', if you will, all the connections associated with a port I
    > designate in a client-server connection, upon or through which I've
    > established a communications socket (bear with me if this is rambling
    > a bit). Somewhere in the system, something is keeping track of all
    > the connections I establish through that port, and IO::Select helps me
    > look at them all.
    >
    > How's that so far?


    Sort of ok-ish :)

    IO::Select is one of the ways to package up a load of file handles, and
    check them in bulk.

    The file handles are most often connected to sockets, but don't have to
    be. They are most often all of the same type, but they don't have to be.

    But in the most used configuration, IO::Select does what you describe.
    So, by the way, does the perl builtin select. IO::Select just gives you
    a much nicer and easy to use interface.

    Martien
    --
    |
    Martien Verbruggen | I took an IQ test and the results were
    | negative.
    |
    Martien verbruggen, May 2, 2007
    #10
  11. Monty

    Monty Guest

    Ok, so I'm not too far off on my thinking. If you'd be so kind, I'd
    like to 'talk out' the level of understanding I have about sockets,
    ports, and maybe ask, later, about these file handles associated with
    them. Some how I'm a bit surprised that the can_read method of
    IO::Select in regards to sockets involves file handles (not entirely
    surprised; everything in UNIX is a file). I expected something else,
    but what else, I don't know.

    With the coding of a new IO::Socket::INET I specify, among other
    things, a port and a Listen parameter, which in this case is greater
    than 1, meaning I can have more than one communication 'stream' that
    is separate and distinct from others on that port. The only education
    I have along these lines is a brief explanation of FTP, where I'm told
    communications between MyComputer and YourComputer are established via
    a well-known port (21, I believe) and once the two systems agree to
    talk, they also agree to further the conversation on a not-well-known
    port, freeing up 21 for further FTP requests.

    Is something similar going on with my socket? That would clear up one
    part of the mystery.

    The second, these file handles, leads me to believe that somewhere on
    the system I would expect to find a file designated as a socket (with
    Solaris, that designation is noted by the '=' at the end of the file
    name). Is that the case?
    Monty, May 2, 2007
    #11
  12. Monty

    Guest

    Monty <> wrote:
    >
    > In practice, I won't need to refresh myself with the underlying
    > mechanisms, but they are important to learn from.
    >
    > So this is what I've got from all this so far: IO::Select allows me to
    > 'peruse', if you will, all the connections associated with a port I
    > designate in a client-server connection,


    IO::Select operates on the file handles that you stuff into it. In this
    case, such stuffing is done with both the "new" call and in the "add" call.

    IO::Select does not know or care how you arrived at the file handles which
    you stuff into it. They could come from the same port, from different
    ports, from named pipes or other special files, whatever.


    > upon or through which I've
    > established a communications socket (bear with me if this is rambling
    > a bit). Somewhere in the system, something is keeping track of all
    > the connections I establish through that port,


    The "somewhere" and "something" are in the statements:

    $sel = new IO::Select( $lsn );

    and then later in the

    $sel->add($new);

    So it isn't the system that is keeping track, it is you, through your
    code, who is keeping track.


    > and IO::Select helps me
    > look at them all.


    It helps you know which ones are immediately available for reading (or, in
    the case of $lsn, available for accepting) without blocking.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
    , May 2, 2007
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. jeff
    Replies:
    0
    Views:
    1,496
  2. Rick
    Replies:
    0
    Views:
    1,123
  3. Gaurav Khanna [.NET MVP]

    Re: System.Net.Sockets.Tcplistener

    Gaurav Khanna [.NET MVP], Jul 25, 2003, in forum: ASP .Net
    Replies:
    0
    Views:
    3,408
    Gaurav Khanna [.NET MVP]
    Jul 25, 2003
  4. Didatus

    UNIX Domain Sockets

    Didatus, Aug 18, 2003, in forum: Perl
    Replies:
    1
    Views:
    1,518
  5. Iceberg

    Carriage Returns and sockets

    Iceberg, Sep 6, 2003, in forum: Perl
    Replies:
    1
    Views:
    1,123
    Iceberg
    Sep 6, 2003
Loading...

Share This Page