Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Problem with sockets--atomic read.

Posted on 1997-11-17
1
Medium Priority
?
435 Views
Last Modified: 2013-12-26
I'm having a problem performing a read() call and retrieving all of the data.

I'm using IRIX 5.3 on an SGI Indy.  Here is the situation:

I have a socket opened for TCP/IP communication.  My client
process performs a writev() call.  The writev() is passed an
iovec with 2 buffers in it.  The total size of the two
buffers is less than PIPE_BUF (aka: PIPE_MAX).  The writev()
call returns to me with a positive value which is equal to
the number of bytes I expect to write.  I believe PIPE_BUF
is 10240 bytes, and my writev() call is writing 3875 bytes
(well below PIPE_BUF).  My server process then performs a
select() call to check for data on the socket and follows
that with a read().  The select() call is only checking for
data on a single socket and is used so that I can timeout
the recv() without using signals.  Anyway, the select()
detects the data on the socket and then I perform a recv().  
However, I am only able to read about 1500 bytes of the
message.  If I place a sleep(1) call just prior to the
recv() I get the whole message (3875 bytes).  This would
leave me to believe that recv() is returning prior to all
the data arriving on the socket.  I would think that an
atomic write on a TCP/IP socket would gurantee that the
message is received atomically as well, but this does not
seem to be the case.  I am wondering if there is some limit
imposed on TCP/IP sockets that is less than PIPE_BUF than I
should be using or do I just need to put that recv() call in
a loop with an accumulator and just keep trying to read
until all the data arrives?

Thanks,
Barry M. Caceres
barryc@alumni.caltech.edu
0
Comment
Question by:barryc
1 Comment
 
LVL 4

Accepted Solution

by:
jos010697 earned 800 total points
ID: 1295610
Yep, you ansered your own question in your last sentence (see
above). It's quite peculiar indeed -- the writev() call can
send data atimically, while there's no guarantee at all that
recv() _receives_ the data in one sweep. The atomiicity simply
means that no other interleaved writes are done to a socket;
it doesn't mean that the data is not chopped up in smaller
parts though. A simple loop could do the job for you:

for (; c= recv(sock, buf, size, 0); c >= 0; size-= c)
   if (!size)
      break;

if (c < 0)
   /* check errno here */

kind regards,

Jos aka jos@and.nl
0

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Want to learn how to record your desktop screen without having to use an outside camera. Click on this video and learn how to use the cool google extension called "Screencastify"! Step 1: Open a new google tab Step 2: Go to the left hand upper corn…

886 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question