所以我(可耻地)使用TerminateThread代替我的代码中recv()函数的正确超时。我刚刚实现了select(),这是一个很好的实践,但它似乎无法处理我需要接收数据的大小和速度。
DWORD WINAPI recv_low(LPVOID randparam) {
fd_set fd;
timeval timeout;
FD_ZERO(&fd);
FD_SET(UseSocket,&fd);
timeout.tv_sec = 5;
timeout.tv_usec = 0;
int sel = 0;
iResult2 = 0;
sel = select (UseSocket+1,&fd,NULL,NULL,&timeout);
if (sel != 0 ) {
iResult2 = recv(UseSocket, recvbuf, recvbuflen, 0);
}
return 1;
}
接收功能的代码具有正确的超时。 它适用于少量数据,但是当我启动并开始接收每秒65535的缓冲区时,它会完全崩溃并且我的程序退出(奇怪的是,返回代码为0)。
但是,如果我使用旧方法:
DWORD WINAPI recv_low(LPVOID randparam) {
iResult2 = 0;
iResult2 = recv(UseSocket, recvbuf, recvbuflen, 0);
return 1;
}
int main() {
DWORD dwrecvthreadId;
HANDLE recvthread = CreateThread(NULL,0,recv_low,NULL,0,&dwrecvthreadId);
WaitForSingleObject(recvthread, 5000);
if (iResult2 > 0) //Do stuff
else if ( iResult2 == 0 ) {
TerminateThread(recvthread, 0);
}
}
按预期完美运作;它会在不退出的情况下接收数据。
现在至于为什么会这样,我没有丝毫的线索。我试图向后走,看看我的代码中的其他内容可能导致我的程序以返回代码0退出,但我无法找到它实际上绊倒的地方并返回。 我不得不相信它与select()或至少我对它的使用有关。
任何人有任何提示吗? (是的,我为不正确的伪代码道歉。我不打算发布我程序的疯狂大小的主要功能。)
编辑:进一步发展;问题的根源是与select()有关。我设法发现当我发送大缓冲区时(使用我在上面设置的select()机制),recv()不会读取它已发送的所有数据。例如,我发送了6个“消息”,全部包含65530个字节(仅用于测量)。 recv()会告诉我它读了多少。第一个缓冲区读取为12524字节,下一个缓冲区读取为14952,依此类推。这似乎是我的问题的基础。