我有一个事件驱动的网络服务器程序。此程序接受来自其他主机上的其他进程的连接。在同一远程IP上可能有许多来自不同端口的短期连接。
目前,我有一个调用accept()
的while(1)
循环,然后产生一个线程来处理新的连接。读取消息后,每个连接都会关闭。在远程端,消息发送后连接关闭。
我希望通过缓存打开的套接字FD来消除建立和拆除连接的开销。在发送者端,这很简单-我只是不关闭连接,而是保留它们。
在接收器端,这有点困难。我知道我可以将accept()
返回的FD存储在一个结构中,并使用poll()
或select()
监听所有此类套接字中的消息,但我希望同时通过accept()
监听新连接,并通过监听所有缓存的连接。
如果我使用两个线程,一个在poll()
上,一个在accept()
上,那么当accept()
调用返回(打开一个新连接)时,我必须唤醒等待旧连接集的另一个线程。我知道我可以用signal和pselect()
做到这一点,但是对于这么简单的东西来说,这整个混乱的工作似乎太多了。
有没有什么方法可以让我同时处理打开的新连接和在旧连接上发送的数据?
发布于 2012-10-31 17:45:07
您可以使用listen,然后使用select或poll,然后使用accept
if (listen(socket_fd, Number_connection) < 0 )
{
perror("listen");
return 1;
}
fd_set set;
struct timeval timeout;
int rv;
FD_ZERO(&set); /* clear the set */
FD_SET(socket_fd, &set); /* add our file descriptor to the set */
timeout.tv_sec = 20;
timeout.tv_usec = 0;
rv = select(socket_fd + 1, &set, NULL, NULL, &timeout);
if (rv == -1)
{
perror("select"); /* an error occurred */
return 1;
}
else if (rv == 0)
{
printf("timeout occurred (20 second) \n"); /* a timeout occurred */
return 1;
}
else
{
client_socket_fd = accept (socket_fd,(struct sockaddr *) &client_name, &client_name_len);
}
发布于 2010-08-11 20:42:47
我会把一个监听器放在单独的进程(线程)中,以免把事情搞糟。并在另一个上运行工作进程以处理现有套接字。实际上,没有必要使用非阻塞监听器。并且运行两个线程时没有线程开销。
它应该是这样工作的:在侦听器线程上接受,直到它返回客户端套接字的描述符,并将其传递给在其上执行所有读/写工作的worker。
如果你想监听多个端口,并且不想让每个监听器拥有一个进程,我建议你在O_NONBLOCK中设置套接字,并执行如下操作:
// loop through listeners here and poll'em for read
// when read is successful call accept, get descriptor,
// pass it to worker and continue listen
while(1){
foreach( serverSocket in ServerSockets ){
if( serverSocket.Poll( 10, SelectRead ) ){
clientSocket = serverSocket.Accept();
// pass to worker here and release
}
}
}
https://stackoverflow.com/questions/3444729
复制相似问题