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

Okay here is the situation. I'm trying to connect to MSN's IM servers (a giant headache) and I have all the code. In fact it used to work just fine, and occasionaly still does. The problem is that sometimes data seems stuck. For instance sometimes it just sets there until you send it another IM then it processes the previous IM. Which lead me to beleive that it had to do with buffers and my reading of the socket. So I read and read and re-read and from all I could tell IO::Socket::INET is set to autoflush by default. Which I thought meant that it would flush the buffered data. I could be way off all together I don't know. I am currently useing the following code to check the socket and then read from it.

while (1) { my @ready; @ready = $Select->can_read(1); foreach $fh (@ready) { my $fn = $fh->fileno; unless ($_ = $fh->getline()) { $Select->remove($fh); next; } # work with $_ here } }

Thats not the exact code but the removed stuff has nothing to do with the sockets. Now I wonder if the problem might not lie with getline(). If I call getline() and there is more than one line, shouldn't the handle still be returned by can_read() the next time threw the loop?

If you could help me with this I would be very thankful. I kind of inherited the socket code, I mostly work with the exchange of data with the server because this code worked fine up until recently.

BTW I have checked the $Select and I am fairly sure that the socket is staying open and in there. There are times whene there are multiple sockets in that and times when there is only one, but it never drops to 0. In other words its acting correctly.

Thanks agian for any ideas or help with the sockets.


___________
Eric Hodges

Replies are listed 'Best First'.
Re: Windows Sockets Seems stuck
by tye (Sage) on Mar 20, 2004 at 05:10 UTC

    Autoflushing isn't the solution to this buffering problem.

    I'll guess that getline() does buffered I/O. This means that, if two messages are ready to be read, getline() might read them both into its buffer when you call it. Then it splits off the first line and returns it to you. Then you ask select to tell you when there is more data to be read off the socket.

    Well, there isn't any more data to be read off the socket. But there is more data in getline()'s buffer.

    I'd probably do this more like:

    my %buf; while (1) { my @ready = $Select->can_read(1); foreach $fh ( @ready ) { while( sysread( $fh, $buf{$fh}, 1024, length($buf{$fh}) ) ) { if( $buf{$fh} =~ s#(.*$/)## ) { my $line= $1; dostuffwith( $line ); } } } }

    - tye        

      Thank you soooo much. BTW I took out the while ( ) and just did the sysread. Not sure thats best but it got stuck in the while loop forever if I didn't.


      ___________
      Eric Hodges
Re: Windows Sockets Seems stuck
by eric256 (Parson) on Mar 20, 2004 at 04:40 UTC

    As an update I've done some packet sniffing and MSN continues to send all the data. My program just isn't reading the info out of the socket. In fact it stops half way threw a single packet. There doesn't appear to be anything different or odd with that packet and it sticks on different packets each time.


    ___________
    Eric Hodges