12

I have a server that sends data to a client every 5 seconds. I want the client to block on read() until the server sends some data and then print it. I know read () is blocking by default. My problem is that my client is not blocking on read(). This is very odd and this does not seem to be a normal issue.

My code prints "Nothing came back" in an infinite loop. I am on a linux machine, programming in c. My code snippet is below. Please advice.

while(1)
{
    n = read(sockfd, recvline, MAXLINE);
    if ( n > 0) 
    {
        recvline[n] = 0;    
        if (fputs(recvline, stdout) == EOF)
            printf("fputs error");
    }
    else if(n == 0)
        printf("Nothing came back");
    else if (n < 0)
        printf("read error");
}
return; 
5
  • 3
    Have you checked that the connection is open (i.e sockfd is valid)? Commented Oct 7, 2012 at 22:52
  • 20
    A return value of 0 from read() means the other end (the server) closed the socket. Commented Oct 7, 2012 at 22:55
  • @Ed Heal : Yes, it is valid. I have a check for that. Commented Oct 8, 2012 at 16:10
  • @Greg : Well, the thing is that the server sends data every 5 seconds. Unless the client waits for the server to send, it will get 0 each time. Commented Oct 8, 2012 at 16:10
  • 6
    No it won't. Zero means the peer closed the connection. It never means there was no data. In blocking mode read() will block; in non-blocking mode if there is no data it will return -1 with errno set to EAGAIN or EWOULDBLOCK depending in your platform. Commented Oct 9, 2012 at 0:35

3 Answers 3

15

There may be several cause and several exceptions are possible at different place:

  1. check socket where you create:

    sockfd=socket(AF_INET,SOCK_STREAM,0);  
    if (sockfd==-1) {
        perror("Create socket");
    }
    
  2. You and also enable blocking mode explicitly before use it:

    // Set the socket I/O mode: In this case FIONBIO  
    // enables or disables the blocking mode for the   
    // socket based on the numerical value of iMode.  
    // If iMode = 0, blocking is enabled;   
    // If iMode != 0, non-blocking mode is enabled.
    ioctl(sockfd, FIONBIO, &iMode);  
    

    or you can use setsockopt as below:

     struct timeval t;    
     t.tv_sec = 0;
     tv_usec = 0;
     setsockopt(
          sockfd,     // Socket descriptor
          SOL_SOCKET, // To manipulate options at the sockets API level
          SO_RCVTIMEO,// Specify the receiving or sending timeouts 
          const void *(&t), // option values
          sizeof(t) 
      );   
    
  3. Check Read function call (Reason of bug)

    n = read(sockfd, recvline, MAXLINE);
    if(n < 0){  
        perror("Read Error:");
    }  
    
  4. Also check server code!:

    1. May your server send some blank(non-printable, null, enter) charter(s). And your are unaware of this. Bug you server code too.

    2. Or your server terminated before your client can read.

  5. One more interesting thing, Try to understand:

    When you call N write() at server its not necessary there should be N read() call at other side.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the elaborate reply, man. I shall try bug fixing the server also and see if it is sending some wierd stuff.
Blocking mode is the default: you don't have to set it explicitly. The code in (2) that calls setsockopt() with arguments of &0 and sizeof(sockfd) is complete nonsense and will not compile. Downvote.
@EJP : I know default mode is blocking. I just wanted to say how to explicitly set blocking mode(or reset to blocking mode). FOR COMPILE ERROR: I corrected the code of setsock() option and My REQUEST to you : please verify and if its a still wrong Please rectify so that one can get correct help..Thanks EJP!
Make also sure that your receive-buffer and its size is "initialized" correctly. E.g in this case recvline and MAXLINE
4

What Greg Hewgill already wrote as a comment: An EOF (that is, an explicit stop of writing, be it via close() or via shutdown()) will be communicated to the receiving side by having recv() return 0. So if you get 0, you know that there won't be any data and you can terminate the reading loop.

If you had non-blocking enabled and there are no data, you will get -1 and errno will be set to EAGAIN or EWOULDBLOCK.

1 Comment

I dont think this is the problem. The server is in a infinite loop, it keeps sending data to the client every 5 seconds. The server, bydesign, is not supposed to shut down at all.
2

What is the value of MAXLINE?

If the value is 0, then it will return 0 as well. Otherwise, as Grijesh Chauhan mention, set it explcitly to blocking.

Or, you may also consider using recv() where blocking and non-blocking can be specified. It has the option, MSG_WAITALL, where it will block until all bytes arrived.

n = recv(sockfd, recvline, MAXLINE, MSG_WAITALL);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.