Я пишу небольшое приложение VOIP, такое как Skype, которое сейчас работает неплохо, но я столкнулся с очень странной проблемой.Weird Winsock recv() slowdown
В одном потоке я вызываю в течение некоторого цикла (true) функцию winsock recv() дважды за каждый проход, чтобы получить данные из сокета. Первый вызов получает 2 байт, которые будут отлиты в (короткий), а второй вызов получает оставшуюся часть сообщения, которая выглядит как:
Полного сообщение: [2 байт заголовок | Сообщение, длина, определяемая заголовком 2Byte]
Эти пакеты круглые около 49/с, что будет около 3000 байт/с.
Содержание этих пакетов - это аудиоданные, которые преобразуются в волну.
С ioctlsocket()
Я определяю, есть ли какие-либо данные в сокете или нет в каждом «сообщении», которое я получаю (2 байта + данных). Если что-то есть в сокете сразу после того, как я получил сообщение в пределах while(true) loop
потока, сообщение будет получено, но оно будет отброшено, чтобы работать с задержкой нарастания.
Эта концепция работает очень хорошо, но вот проблема:
Хотя моя VOIP программа работает, и когда я паралельно загрузки (например, через браузер) файл, всегда получает слишком много данных, сложенных на сокете, т.к. при загрузке, recv() loop
, похоже, замедляется. Это происходит в каждой ситуации загрузки/выгрузки, кроме фактической загрузки/загрузки voip.
Я не знаю, откуда взялось это поведение, но когда я фактически отменяю каждую загрузку, кроме трафика voip моего приложения, мои приложения снова работают отлично.
Если программа работает отлично, функция ioctlsocket()
записывает 0 в переменную bytesLeft var, определенную в классе, откуда приходит функция приема.
Знает ли кто-нибудь, откуда это взялось? Я приложу мой получить функцию вниз:
std::string D_SOCKETS::receive_message(){
recv(ClientSocket,(char*)&val,sizeof(val),MSG_WAITALL);
receivedBytes = recv(ClientSocket,buffer,val,MSG_WAITALL);
if (receivedBytes != val){
printf("SHORT: %d PAKET: %d ERROR: %d",val,receivedBytes,WSAGetLastError());
exit(128);
}
ioctlsocket(ClientSocket,FIONREAD,&bytesLeft);
cout<<"Bytes left on the Socket:"<<bytesLeft<<endl;
if(bytesLeft>20)
{
// message gets received, but ignored/thrown away to throw away
return std::string();
}
else
return std::string(buffer,receivedBytes);}
Учитывая, что ваша программа VOIP и другая программа разделяют одну и ту же полосу пропускания, не ожидалось бы, что большая загрузка другой программой замедлит прием данных вашей программы на какую-то сумму? Особенно, если вы используете TCP, а конфликт пропускной способности заставляет один из пакетов TCP вашего потока отбрасываться ... тогда отправителю придется отправить его повторно, и пока ваше приложение не увидит, что больше данных не поступит. Также TCP делает автоматическое дросселирование скорости передачи, чтобы избежать перегрузок, так что это также может быть фактором. Для VOIP часто лучше использовать UDP ... –