我想检查客户端是否发送了一些新的数据。这实际上告诉我,我总是有新的数据:即使没有新的数据,FD_ISSET总是正确的?
bool ClientHandle::hasData()
{
fd_set temp;
FD_ZERO(&temp);
FD_SET(m_sock, &temp);
//setup the timeout to 1000ms
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 1000;
//temp.fd_count possible?
if (select(m_sock+1, &temp, nullptr, nullptr, &tv) == -1)
{
return false;
}
if (FD_ISSET(m_sock, &temp))
return true;
return false;
}
我用Java客户端连接,并发送我的构造函数的读取里面“连接”消息:
ClientHandle::ClientHandle(SOCKET s) : m_sock(s)
{
while (!hasData())
{
}
char buffer[5];
recv(m_sock, buffer, 4, NULL);
auto i = atoi(buffer);
LOG_INFO << "Byte to receive: " << i;
auto dataBuffer = new char[i + 1]{'\0'};
recv(m_sock, dataBuffer, i, NULL);
LOG_INFO << dataBuffer;
//clean up
delete[] dataBuffer;
}
这似乎工作的权利。之后,我继续检查是否有新数据,即使java客户端不发送任何新数据,它总是真实的。
这里是java客户端。不要评价我只是为了检查连接。它不会像这样以char []的形式发送大小信息。
public static void main(String[] args) throws UnknownHostException,
IOException {
Socket soc = null;
soc = new Socket("localhost", 6060);
PrintWriter out = new PrintWriter(soc.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(
soc.getInputStream()));
if (soc != null)
System.out.println("Connected");
out.write("10\0");
out.flush();
out.write("newCon\0");
out.flush();
out.close();
in.close();
soc.close();
}
那么hasData FD_ISSET方法有什么问题?
时调用第二个recv,那么数据没有问题,但是当我看到其他答案时,它将在不同条件下返回true。 (不仅仅是它包含我认为的新数据),所以hasdata方法是不正确的。所以我需要补充一点。 – BennX
@BennX'hasData()'几乎是正确的:你不应该在断开的套接字上使用'FD_SET'。 'recv()'返回一个正数,如果它获得数据,则返回'0',如果客户端断开连接,则返回'-1'。我更新了我的答案以添加更多解释。 – nouney
所以要检查我是否有数据,我只需recv并处理它,如果有新的?我想我可以在选择数据之前用select来检查它。 – BennX