【发布时间】:2012-01-30 06:18:32
【问题描述】:
我正在尝试编写一个同时处理多个客户端的服务器。显然我应该使用select。我找到了很多教程,但没有一个能处理写作。
我知道我应该如何读取数据,但是在我的“循环”中处理写回客户端的正确方法是什么?
提前致谢。
【问题讨论】:
标签: c++ sockets asynchronous
我正在尝试编写一个同时处理多个客户端的服务器。显然我应该使用select。我找到了很多教程,但没有一个能处理写作。
我知道我应该如何读取数据,但是在我的“循环”中处理写回客户端的正确方法是什么?
提前致谢。
【问题讨论】:
标签: c++ sockets asynchronous
实际上,我认为您想使用 poll() 而不是 select() 但这不是重点。要写入多个客户端,您需要确保不使用阻塞写入。您可能不会检测特定对象是否可以消化更多数据而侥幸,因此您可能不需要在编写时使用 poll()(或 select())。但是,如果您想为客户端以不同的速度消费数据做好准备,您可能希望在客户端可以消化更多数据时收到通知。
除此之外,poll() 或 select() 可以通知读取缓冲区中可用的数据或写入缓冲区中可用的空间。除了需要设置不同的标志外,用法几乎相同。
【讨论】:
如果您有想要发送到特定套接字的数据,那么当该套接字的输出缓冲区中有可用空间时,您需要 select() 返回。告诉 select() 这样做的方法类似于使用 select() 仅用于读取 - 除了您也在第二个 fd_set 对象上执行 FD_SET。
int socks[10] = {... some client sockets...}
while(1)
{
fd_set readSet, writeSet;
FD_ZERO(&readSet);
FD_ZERO(&writeSet);
int maxSock = -1;
for (int i=0; i<10; i++)
{
FD_SET(socks[i], &readSet);
if (socks[i] > maxSock) maxSock = socks[i];
if (IHaveDataToSendToThisSocket(i)) // implement this function as appropriate to your program
{
FD_SET(socks[i], &writeSet);
if (socks[i] > maxSock) maxSock = socks[i];
}
}
int ret = select(maxSock+1, &readSet, &writeSet, NULL, NULL);
if (ret < 0)
{
perror("select() failed");
break;
}
// Do I/O for sockets that are ready
for (int i=0; i<10; i++)
{
if (FD_ISSET(socks[i], &readSet))
{
// there is data to read on this socket, so call recv() on it
}
if (FD_ISSET(socks[i], &writeSet))
{
// this socket has space available to write data to, so call send() on it
}
}
}
【讨论】: