write () и send () решают ошибки => разница? - PullRequest
4 голосов
/ 29 января 2012

может быть какая-то разница в решении ошибок между этими двумя функциями ?:
На этот вопрос возник другой вопрос ... всегда ли количество символов совпадает с количеством байтов?
Для получения дополнительной информации: я использую его в C на Linux для соединения сокетов TCP (sys / socket.h) Спасибо за ваши ответы.

send ()
запись ()

Return:
написать ():
В случае успеха возвращается количество записанных байтов (ноль означает, что ничего не было записано). В случае ошибки возвращается -1 и значение errno устанавливается соответствующим образом. Если число равно нулю, а дескриптор файла ссылается на обычный файл, 0 будет возвращено без какого-либо другого эффекта. Для специального файла результаты не переносимы.

отправить ():
Вызовы возвращают количество отправленных символов или -1, если произошла ошибка.

Вопрос от stackoverflow, который говорит, что эти методы должны быть одинаковыми с использованием нулевого флага.
здесь

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;

Ответы [ 2 ]

3 голосов
/ 29 января 2012

Они оба будут возвращать одинаковое количество записанных байтов (== символов в этом случае. ИСКЛЮЧИТЕ это:, и сообщение не передается.

Другими словами, в зависимости от размера записываемых данных, write () может завершиться успешно, когда send () может завершиться неудачей.

1 голос
/ 29 января 2012

Количество байтов == количество символов, поскольку стандарт C требует, чтобы char было 1-байтовым целым числом.

write(): Да, он возвращает количество записанных байтов. Но: это не всегда ошибка, если она не возвращает столько байтов, сколько должно быть написано. Особенно не для связи по TCP. Сокет может быть неблокирующим или просто занятым, в этом случае вам нужно будет переписать еще не записанные байты. Такое поведение может быть достигнуто так:

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(): То же самое применимо и здесь, с той лишь разницей, что EOF указывается возвращением 0, и это не ошибка. Опять же, вы должны повторить чтение, если хотите получить все доступные данные из сокета.

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 */

Вы можете увидеть мою реализацию простого вспомогательного класса TCP с использованием этой техники на https://github.com/H2CO3/TCPHelper/blob/master/TCPHelper.m

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...