gpt4 book ai didi

c++ - 选择——几个问题

转载 作者:行者123 更新时间:2023-11-28 07:31:47 24 4
gpt4 key购买 nike

我有几个关于select函数的问题,我写了这段代码:

void TCPSerwer::sel()
{
struct timeval tv = {1, 0};
fd_set temp_list = m_RecvList;
//if(select(m_fdmax + 1, &temp_list, NULL, NULL, &tv) == SOCKET_ERROR)
if(select(0, &temp_list, NULL, NULL, &tv) == SOCKET_ERROR)
{
perror( "select" );
exit( 1 );
}

for(int i = 0; i <= m_fdmax; i++ )
{
if(FD_ISSET(i, &temp_list))
{
// New connection
if(i == m_ListenSocket)
{
acceptClient();
}

// Data from client
else
{
PacketHeader header;
int nbytes = recv(i, (char*)(&header), sizeof(PacketHeader),

// Error
if(nbytes < 0)
{
disconnectClient(i);
}
// success
else
{
std::cout << "type: " << header.type << " len: " << header.length << std::endl;
}
}
}
}
}

我可以给第一个参数来选择函数,但我不能这样做,但为什么呢?为什么 a 应该先给出 arg 来选择? m_fdmax 是最大的套接字数量,但是这段代码在没有这个参数的情况下也能工作。

下一个问题是,为什么select需要超时?当我不提供此 arg 时,选择将所有套接字标记为可读的套接字,但选择在套接字没有任何数据可读时执行此操作。当我给这个 arg 我没有这个问题。但是为什么?

如果 m_fdmax 是最大数量的套接字,我必须在关闭连接时找到下一个最大数量的套接字,对吗?我应该这样做:

int size = m_ClientVector.size();
for(int i = 0; i < size; i++)
{
if(m_ClientVector[i] > m_fdmax)
m_fdmax = m_ClientVector[i];
}

最佳答案

I can give first arg to select function and i can don't do that, but why ? Why a should give first arg to select ? m_fdmax is highest number of socket, but this code working without this arg.

Read the documentation . select() Windows 上的函数会忽略第一个参数,因此传递给它的内容无关紧要。

Next question is, why select need timeout ?

它不需要超时,但如果需要,您可以可选提供超时。这样,如果在超时之前未达到请求的套接字状态,select()仍然可以退出并且不会无限期地死锁调用线程,允许它做其他事情。

When i don't give this arg select marks all socket as socket that can be readable but select doing this when socket haven't any data to read.

如果您不提供超时,select()无限期地等待,直到请求的套接字状态实际发生。如果套接字有数据可读,它可以被标记为可读,但如果它已经被 gracefully 也可以被标记为可读。被对方断开。随后调用 recv()会告诉您是哪种情况(recv() 出错时返回 -1,断开连接时返回 0,数据时返回 >0)。同样,read the documentation .

if m_fdmax is highest number of socket, i have to find next highest number of socket when i close connection, Right ?

如果你想计算最高套接字号(Windows 不关心,但其他平台会关心),那么你每次调用 select() 时都必须重新计算最高套接字号。 ,或者至少在您重新准备 fd_set 时结构(每次调用 select() 时都需要这样做)。

And i should doing this that

在 Windows 上,没有。在其他平台上,是的。

话虽如此,请在 Windows 上尝试此代码:

void TCPSerwer::sel()
{
struct timeval tv = {1, 0};
fd_set temp_list = m_RecvList;

int ret = select(0, &temp_list, NULL, NULL, &tv);
if (ret == SOCKET_ERROR)
{
perror( "select" );
exit( 1 );
}

if (ret == 0) // timeout
return;

for(u_int i = 0; i < temp_list.fd_count; ++i)
{
SOCKET s = temp_list.fd_array[i];

// New connection
if (s == m_ListenSocket)
{
acceptClient();
continue;
}

// Data from client

PacketHeader header;

char *pheader = (char*) &header;
int nbytes = 0;

do
{
ret = recv(s, pheader, sizeof(PacketHeader)-nbytes, 0);

// success
if (ret > 0)
nbytes += ret;
}
while ((ret > 0) && (nbytes < sizeof(PacktHeader)));

// Error or disconnect
if (nbytes < sizeof(PacktHeader))
{
disconnectClient(i);
continue;
}

// success
std::cout << "type: " << header.type << " len: " << header.length << std::endl;
}
}

关于c++ - 选择——几个问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17533190/

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