Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading message from socket in C

Tags:

c

linux

sockets

I try to understand reading from socket in C (Linux), this is only part of code:

while(success == 0) {

    while((n = read(sockfd, buffer, BUFFSIZE, 0)) > 0) {
        printf("%s",buffer);
        bzero(buffer,BUFFSIZE);
    }
    success = 1;
    printf("###");

}

The message is printed, but the three hashes (###) are never print? Why? The program seems to block on read(). Here i do just printing, but what i need to do is to buffer the whole message and then process it.

like image 450
Asheron2332 Avatar asked Mar 14 '11 20:03

Asheron2332


3 Answers

The program on the other end of the socket is not closing it, nor shutting down its writes (which are your reads), so your end does not know that everything is finished - indeed, logically it isn't finished until the other end says there is nothing more for you to read.

Typically, your application level logic needs to know in advance how much to read, or reads until a certain terminator is received, or the other end gracefully closes or shuts down the socket.

(Non-blocking I/O is something else entirely - it allows you to do other things whilst reading from sockets efficiently in a single thread, but it doesn't solve the problem of determining when you've finished reading from a socket, which is your problem.)

like image 194
Will Avatar answered Nov 15 '22 05:11

Will


You need to know how large is the message you're receiving, and keep reading until you have the whole message (a read can return only part of your message).

do {
    nread = read(s, buf, to_read);
    if (nread < 0 && errno == EINTR)
            continue;
    if (nread < 0) {
            perror("read");
            exit(1);
    }

    if (nread == 0) {
            printf("socket closed");
            ... do something appropiate ...
            ... (reconnecting/exiting the loop with an error/...) ...
    }

    to_read -= nread;
    buf += nread;
} while (to_read > 0); 

to_read is the length in bytes you're expecting to read. buf has enough space for it. After every read, update to_read and buf accordingly. And, of course, you should deal with errors correctly.

like image 35
ninjalj Avatar answered Nov 15 '22 05:11

ninjalj


You have to now when to stop reading from the socket, otherwise the socket will block your program until it receives more data. Have a look at non-blocking sockets if you want to know how to create sockets that don't block your program.

ief2

like image 36
v1Axvw Avatar answered Nov 15 '22 05:11

v1Axvw