почему функция отправки возвращает 0 в сокете, но клиенты должны получать сообщение?

#c #sockets

Вопрос:

 void SendStr(int connfd, std::string str)
{
    uint16_t *len = new uint16_t(str.size());
    const char * lenByte = (char *)len;
    char *sendByte = new char[*len   2]{0};
    memcpy(sendByte,lenByte,sizeof(*len));
    memcpy(sendByte   2, str.c_str(), *len);
    std::cout << "str size " << *len << std::endl;
    //std::cout << "len size " << sizeof(len) << std::endl;

    size_t nleft = *len   2;
    std::cout << "need to send " << nleft << std::endl;
    int nsend = 0;
    while (nleft > 0)
    {
        //std::cout << "sending " << nleft << "bytes" << std::endl;
        if (nsend = (write(connfd, sendByte   nsend, nleft)) < 0)
        {
            if (errno == EINTR)
                continue;
            ERROR_EXIT("send");
        }
        else if (nsend == 0)
            //continue;
            break;
        nleft -= nsend;
        std::cout << "sended " << nsend << " left " << nleft << std::endl;
    }
    std::cout << "send complete" << std::endl;
    delete[] sendByte;
    delete len;
}
 

Полный код находится здесь
Я вижу, что функция записи и отправки возвращает сумму байтов, в то время как здесь возвращает 0, и клиент, похоже, работает нормально, это меня смущает.

Комментарии:

1. К вашему сведению, вы программируете на C , а не на C. Язык C не поддерживает delete[] и std::string и operator new . Пожалуйста, обновите свои теги соответствующим образом.

2. конечно, отредактировано. Спасибо за вашу помощь!

3. Примечание: Запись в сокет обычно означает, что по крайней мере часть данных может быть записана в выходной буфер сокета. Это не значит, что данные попали на провод или когда-либо попадали на другую сторону. в случае TCP сетевой стек будет продолжать пытаться отправить данные до тех пор, пока он больше не сможет это сделать. Обычно вы замечаете, что данные не были отправлены, когда вы заполнили буфер, и получаете сообщение об ошибке от записи в сокет или блок при закрытии сокета, и выяснить, что было или не было отправлено, может оказаться непросто.

4. Да, спасибо за информацию, она действительно мне очень помогает!

Ответ №1:

То, что вы видите, неправильно.

В этом заявлении

         if (nsend = (write(connfd, sendByte   nsend, nleft)) < 0)
 

Результат сравнения (write(connfd, sendByte nsend, nleft)) < 0 оценивается как nsend . Это произойдет 1 , если условие истинно и 0 если условие ложно. Похоже, вы неправильно понимаете этот результат сравнения как сумму байтов.

Если вы хотите назначить то, что возвращается, write nsend и затем сравнить, это должно быть так:

         if ((nsend = write(connfd, sendByte   nsend, nleft)) < 0)
 

Добавление: Единственный способ write вернуть 0 в сокете-это если nleft равно 0.

Комментарии:

1. Да, я не проверял скобки, это классический вопрос. Спасибо за вашу помощь!