我正在尝试编写一次处理多个客户端的服务器。显然我应该使用select
。我找到了很多教程,但没有一个能够处理写作。
我知道我应该如何阅读数据,但是在我的'循环'中处理写回客户端的适当方式是什么?
提前致谢。
答案 0 :(得分:3)
如果您有要发送到特定套接字的数据,那么当该套接字的输出缓冲区中有可用空间时,您需要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
}
}
}
答案 1 :(得分:0)
实际上,我认为你想使用poll()而不是select(),但这是重点。要写入多个客户端,请确保不使用阻止写入。您可能无法检测特定内容是否可以消化更多数据,因此在编写时可能不需要使用poll()(或select())。但是,如果您想为使用不同速度数据的客户做好准备,您可能希望在客户端消化更多数据时接收通知。
除此之外,poll()或select()可以通知读缓冲区中可用的数据或写缓冲区中可用的空间。除了需要设置不同的标志外,其用途几乎相同。