views:

151

answers:

3

I've got a TCP server and client written in C that opens up a connection that should be open forever. On the first send, errno returns 0 which is fine. On subsequent sends it gives me an errno 60 which is that the operation timed out. The packet is still recieved by the server though and nothing seems to be wrong. What could cause the the errno being set? Is it best to just ignore this error since it seems to be working correctly?

+3  A: 

Random guess: errno is only set when a function fails. If the function does not fail, errno is left as-is. It is not set to 0. The following is wrong:

send( … );
if (errno) {
    perror("send");
}

Instead, you must check the result of send:

ssize_t res = send( … );
if (-1 == res) {
    perror("send")
}

You can confirm this with the following program:

#include <stdio.h>
#include <unistd.h>

int main() {
    char buf[16];
    ssize_t res;

    read(999, buf, sizeof(buf));
    perror("read");

    write(1, "hello world\n", 12);
    perror("write");
}

which outputs:

read: Bad file descriptor
hello world
write: Bad file descriptor

(Note: assuming STDOUT is fd 1)

derobert
A: 

I think You test only the errno variable, but not the return value of send().

You should examine the errno variable after a function return value indicate that the errno variable was set by the function. If the function does not report that errno was set, the errno variable does not hold a meaningful value.

sambowry
+1  A: 

As others have alluded to, you need to test the return values of Unix system functions...all of them!...in order to interpret errno values in a bulletproof fashion. I refer you to item 6 of the canonical guidelines, Henry Spencer's The Ten Commandments for C programmers :

If a function be advertised to return an error code in the event of difficulties, thou shalt check for that code, yea, even though the checks triple the size of thy code and produce aches in thy typing fingers, for if thou thinkest "it cannot happen to me", the gods shall surely punish thee for thy arrogance.

Jim Lewis