gpt4 book ai didi

c++ - 即使没有新数据,FD_ISSET 也始终为真?

转载 作者:太空狗 更新时间:2023-10-29 21:17:35 25 4
gpt4 key购买 nike

我正在尝试检查客户端是否发送了一些新数据。这实际上告诉我,我总是有新数据:

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 客户端并发送一条“连接”消息,我在 ctor 内部读取了该消息:

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方法有什么问题呢?

最佳答案

So what is wrong with the hasData FD_ISSET method?

其实没有。您对 recv() 的使用存在问题。

如果客户端断开连接,

recv() 将返回 0 并将返回此值,直到您关闭 套接字(服务器端)。您可以找到此信息 in the manual .即使 recv() 返回 0,它也会“触发”select()

知道了这一点,就很容易找出问题所在:您从不检查 recv() 的返回值,因此您无法判断客户端是否仍处于连接状态。但是,您仍然使用 FD_SET 添加它!

#include <sys/types.h> // for ssize_t
#include <stdio.h> // for perror()
ClientHandle::ClientHandle(SOCKET s) : m_sock(s)
{
while (!hasData())
{
}
char buffer[5];
ssize_t ret = recv(m_sock, buffer, 4, NULL);
if (ret == -1) // error
{
perror("recv");
return ;
}
else if (ret == 0) // m_sock disconnects
{
close(m_sock);
// DO NOT FD_SET m_sock since the socket is now closed
}
else
{
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;
}
}

关于c++ - 即使没有新数据,FD_ISSET 也始终为真?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32463627/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com