write() and send() solving errors => difference?

2019-05-05 21:34发布

问题:

could be any difference in solving errors between this two functions?:
To this question brought me another question ... is number of characters always same as number of bytes?
For more info: I use it in C on Linux for TCP socket comunication(sys/socket.h) Thanks for your responses.

send()
write()

Return:
write():
On success, the number of bytes written are returned (zero indicates nothing was written). On error, -1 is returned, and errno is set appropriately. If count is zero and the file descriptor refers to a regular file, 0 will be returned without causing any other effect. For a special file, the results are not portable.

send():
The calls return the number of characters sent, or -1 if an error occurred.

Question from stackoverflow which says that this methods should be same with using flag zero.
here

int client_sockfd;
char* msg;
int length = strlen(msg); 

//first option
if(send(client_sockfd, msg, length, 0) != length) return 1;
else return 0;
//second option 
if(write(client_sockfd, msg, length) != length) return 1;
else return 0;

回答1:

They will both return the same number of written bytes (== characters in this case. EXCEPT note this:

If the message is too long to pass atomically through the underlying protocol, the error EMSGSIZE is returned, and the message is not transmitted.

In other words, depending on the size of the data being written, write() may succeed where send() may fail.



回答2:

Number of bytes == number of characters, since the C standard reuires that char be an 1-byte integer.

write(): Yes, it returns the number of bytes written. But: it's not always an error if it doesn't return as many bytes as it should heva written. Especially not for TCP communication. A socket may be nonblocking or simply busy, in which case you'll need to rewrite the not-yet-written bytes. This behavior can be achieved like this:

char *buf = (however you acquire your byte buffer);
ssize_t len = (total number of bytes to be written out);

while (len > 0)
{
    ssize_t written = write(sockfd, buf, len);
    if (written < 0)
    {
        /* now THAT is an error */
        break;
    }
    len -= written;
    buf += written; /* tricky pointer arythmetic */
}

read(): Same applies here, with the only difference that EOF is indicated by returning 0, and it's not an error. Again, you have to retry reading if you want to receive all the available data from a socket.

int readbytes = 0;
char buf[512];
do {
    readbytes = read(sockfd, buf, 512);
    if (readbytes < 0)
    {
        /* error */
        break;
    }
    if (readbytes > 0)
    {
        /* process your freshly read data chunk */
    }
} while (readbytes > 0); /* until EOF */

You can see my implementation of a simple TCP helper class using this technique at https://github.com/H2CO3/TCPHelper/blob/master/TCPHelper.m



标签: c sockets send