#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. Да, я не проверял скобки, это классический вопрос. Спасибо за вашу помощь!