Maggie Maggie - 3 months ago 19
C Question

transfer integer over a socket in C

What is the appropriate way to transfer an

int
over a socket in C?

What I am doing so far is:

int n = 4;
int tmp = htonl(n);
write(socket, &tmp, sizeof(tmp));


and

int tmp,n;
read(socket, &tmp, sizeof(tmp));
n = ntohl(tmp);


However, the integer received is sometimes 0. Not always, but let's say 2 out of 5 times. It is never some other value, always 0. Why?

UPDATE: Return value from read is -1 and an error is:

Resource temporarily unavailable

Answer

First of all, sizeof(int) may differ on your sender and receiver machine. So I would recommend you to use something like int32_t from stdint.h.

Also, it is not guaranteed that read(..,..,sizeof(int)) will read exactly sizeof(int) bytes - it can read nothing, or it can read less bytes. So, the correct variant will be something more like this:

int send_int(int num, int fd)
{
    int32_t conv = htonl(num);
    char *data = (char*)&conv;
    int left = sizeof(conv);
    int rc;
    do {
        rc = write(fd, data, left);
        if (rc < 0) {
            if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
                // use select() or epoll() to wait for the socket to be writable again
            }
            else if (errno != EINTR) {
                return -1;
            }
        }
        else {
            data += rc;
            left -= rc;
        }
    }
    while (left > 0);
    return 0;
}

int receive_int(int *num, int fd)
{
    int32_t ret;
    char *data = (char*)&ret;
    int left = sizeof(ret);
    int rc;
    do {
        rc = read(fd, data, left);
        if (ret <= 0) {
            if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
                // use select() or epoll() to wait for the socket to be readable again
            }
            else if (errno != EINTR) {
                return -1;
            }
        }
        else {
            data += rc;
            left -= rc;
        }
    }
    while (left > 0);
    *num = ntohl(ret);
    return 0;
}
Comments