【发布时间】:2016-02-19 21:31:26
【问题描述】:
我可以清楚地看到 recvbuf 拥有我期望的所有数据,但 select() 一直返回 1。
现在它被困在else if (iBuffer == 0) {} 的边缘。
SOCKET m_ConnectSocket;
/* The socket setup is done elsewhere but just adding this for clarity
This socket is responsible for sending from the client to the server
and also receives anything the server sends back.
This socket is doing the connect() & initial send()
*/
fd_set set;
struct timeval timeout;
// Set up the file descriptor set.
FD_ZERO(&set);
FD_SET(m_ConnectSocket, &set);
// Set up the struct timeval for the timeout.
timeout.tv_sec = RECV_DELAY_SEC;
timeout.tv_usec = RECV_DELAY_USEC;
int iBuffer = 0;
do
{
iResult = select(m_ConnectSocket, &set, NULL, NULL, &timeout);
if (iResult > 0)
{
iBuffer = recv(m_ConnectSocket, recvbuf, DEFAULT_BUFLEN, 0);
if (iBuffer > 0)
{
string sRecv(recvbuf);
STrace = String::Format("Bytes Received: {0}", iBuffer);
Trace(STrace, TRACE_INFO);
STrace = String::Format("Data Received: [{0}]", gcnew String(sRecv.c_str()));
Trace(STrace, TRACE_INFO);
}
else if (iBuffer == 0)
{
STrace = String::Format("iBuffer empty");
Trace(STrace, TRACE_INFO);
}
else
{
STrace = String::Format("recv failed: {0}", WSAGetLastError());
Trace(STrace, TRACE_ERROR);
}
}
else if (iResult == 0)
{
STrace = String::Format("No data left in buffer");
Trace(STrace, TRACE_INFO);
pMessage->Data(recvbuf);
if (iSentType != pMessage->Type())
{
STrace = String::Format("Message type mismatch: {0} | Expected: {1}", (int)pMessage->Type(), (int)iSentType);
Trace(STrace, TRACE_WARNING);
}
}
else if (iResult == -1)
{
STrace = String::Format("select() error");
Trace(STrace, TRACE_ERROR);
}
} while (iResult > 0);
【问题讨论】:
-
select 在循环中的第一次或后续时间是否返回 1?
-
这是 UDP 连接吗? DEFAULT_BUFLEN 的值是多少?你为什么要通过
m_connectSocket而不是1来选择? (select的第一个参数应该是要检查的文件描述符的数量)。 -
我认为您需要在每次通话前重置
set和timeout。也许错了 -
@Enigma 我错了 - 根据 msdn,该参数被忽略。 (msdn.microsoft.com/en-us/library/windows/desktop/…) 但在 berkeley 套接字中,它应该是最高套接字 + 1 (linux.die.net/man/2/select)
-
@EdHeal 你是绝对正确的; select 改变了 fdset,这就是为什么它将它们作为指针,所以你可以知道哪些套接字亮了,可以这么说。
标签: c++ windows select networking winsock2