develooper Front page | perl.perl5.porters | Postings from November 1999

[ID 19991121.003] quirks with NT Perl socket implementation

From:
Phil Pfeiffer
Date:
November 21, 1999 18:40
Subject:
[ID 19991121.003] quirks with NT Perl socket implementation
Message ID:
01JIM4DFV9GY8ZFQ6T@ACCESS.ETSU.EDU
Hello -

The notes that come with the Perl release kit suggest that bug reports
be mailed to this address, together with any possible suggestions for
fixes.  Sorry if (1) these are old, well-known problems.  Also, sorry for
(2) not providing fixes.  But maybe someone who understands the Perl
socket implementation will ferret out the problems more quickly than 
I ever could.

This semester, one of my grad classes used Perl in a network 
communications project.  We encountered the following two anomalies
in the Perl 5.00503 implementation of the TCP socket API under NT 4.0:

-.  Apparent buffer size limitations.  if one tries to send more than 1460
    bytes from a Perl process to a C++ process along a TCP socket,
    the send() fails.  The corresponding recv() reports that only 1460 bytes
    were received correctly, regardless of how many bytes were sent.

    One of my students speculates that the 1460 byte limitation might be
    a "feature" of Winsock 1.1, since he seems to recall running into
    similar limitations in C++-only code.  I have not bothered to verify his
    conjecture, being temporarily swamped with other concerns.

-.  Apparent buffer size limitations (cont).   Sending a series of messages
    without pause from a Perl client to a C++ server produces the same
    sort of error-- probably for the same reasons.   Putting as little as a
    0.2 second pause into the sequence of sends() every 500 characters
    or so  (select undef, undef, undef 0.2)  seems to eliminate the error.

-.  Getting the "rollover" socket to work correctly.   In a TCP connection,
    accept() returns a second "rollover" socket, distinct from the original 
    receiver socket.  This "rollover" socket, in turn, is *supposed* to field 
    all subsequent communication from the original client, thereby freeing
    the server to accept new inputs from other clients:  e.g.,          

              // if the following call works, from here on out, we should be
              // speaking with the client via rolloverSock, rather than masterSock
             //
            rolloverSock = accept( masterSock );   

     The "rollover socket" mechanism seems to work just fine if the client
     is the first party to send a message, following a connect() request:
     e.g.,

            C++ server                                                             Perl client
               bind( masterSock )
               listen( masterSock, 3 )
               rolloverSock = accept( masterSock ) <-------- connect( )
                                                                       <-------- send( masterSock )
             <send() received by rolloverSock, as desired>

        If, however, the *server* is the first entity to communicate following
        connection establishment, the first message goes awry:

            C++ server                                                             Perl client
               bind( masterSock )
               listen( masterSock, 3 )
               rolloverSock = accept( masterSock ) <-------- connect( )
               send( rolloverSock ) ------------->
                                                   <received by Perl client>
                                                                       <-------- send( masterSock )
             <send() received by masterSock!>
    
That's all that I have to pass along.  *If* I start working more heavily
with porting some C++ wrapper classes to Perl, I may make time to 
look at these problems in more detail.  In the meantime, thanks for
considering this note.

Respectfully,

-- Phil



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About