我正在编写一个像 Skype 这样的小 VOIP 应用程序,它现在工作得很好,但我遇到了一个非常奇怪的问题。
在一个线程中,我在 while(true) 循环内调用 winsock recv() 函数两次,每次运行以从套接字获取数据。第一次调用获得 2 个字节,将被转换为(短),而第二次调用获得消息的其余部分,如下所示:
完整消息:[2 字节标题 | 消息,长度由 2Byte Header 决定]
这些数据包大约是 49/秒,大约是 3000 字节/秒。
这些数据包的内容是转换成波形的音频数据。
随着ioctlsocket()
我确定在我收到的每个“消息”(2字节+数据)中是否有一些数据在套接字上。如果在我收到while(true) loop
线程内的消息后套接字上有东西,则将收到该消息,但会丢弃该消息以防止上行延迟。
这个概念非常有效,但问题是:
当我的 VOIP 程序正在运行并且当我并行下载(例如通过浏览器)一个文件时,总是有太多的数据堆积在套接字上,因为在下载时,recv() loop
似乎实际上变慢了。除了实际的 voip up/download 之外,这在每种下载/上传情况下都会发生。
我不知道这种行为来自哪里,但是当我实际上取消除了我的应用程序的 voip 流量之外的所有上传/下载时,我的应用程序再次完美运行。
如果程序完美运行,该ioctlsocket()
函数会将 0 写入 bytesLeft 变量,该变量在接收函数所在的类中定义。
有人知道这是从哪里来的吗?我将在下面附上我的接收功能:
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);}