chettyharish
chettyharish

Reputation: 1734

Sending 'signed long int' via sockets

I am trying to send a long int number using sockets (from client to server). Both the client and the server are x86 (and identical machines). The client writes 21 long int's to the socket and the server reads it out.

Here is a part of the code.

Server:

long int num = 0;
int ret;
for (int i = 0; i < 21; i++) {
    if ((ret = read(sfd_client, (char *) &num, sizeof(num))) == -1) {
        perror("read");
        exit(1);
    }
    printf("number = %d  = %ld  ret = %d\n", i, num, ret);
}

Client:

for (int i = 0; i < 21; i++) {
    if (write(sockfd_client, &temp[i], sizeof(long int)) == -1) {
        exit(1);
    }
}

I noticed that after calling the read the return value is exactly 8, which means that 8 bytes were read; yet the data is always 0. I don't understand what I am doing wrong. Also I was looking at various functions, and all cater to unsigned numbers but not signed (ntoh and hton family).

NOTE: Also I noticed that the first read() is 8 bytes, but the following ones are only 1 byte.

Whats the best way I can transmit all these numbers? (Also I noticed that the for loop refuses to quit if I have the read statement in there.)

Solution (The problem was the fact that the read was returning less bytes than required, This function solved it)

void read_long(int sockfd_client, char *num) {
    unsigned int size = sizeof(long int);
    int rlen = 0;
    int ret;

    while (rlen < size) {
        if ((ret = read(sockfd_client, (num + rlen), size - rlen)) == -1) {
            perror("read_long");
            exit(1);
        }

        if (ret == 0) {
            perror("socket closed before consumption");
            exit(1);
        }
        rlen += ret;
    }
}

Upvotes: 0

Views: 710

Answers (1)

jarmod
jarmod

Reputation: 78918

[I'm going to repeat my comment as an answer, given that it turned out to be correct]

Note that calling read() with sizeof(num) returns up to sizeof(num) bytes. It might return fewer and it's your responsibility to accumulate them.

Similarly write() does not guarantee to write the requested number of bytes. You need to check the return value from write to see how many bytes were actually written, and then write the remaining bytes.

Upvotes: 3

Related Questions