gpt4 book ai didi

c - 推送服务器的 select() 问题 - c/c++

转载 作者:太空宇宙 更新时间:2023-11-04 03:46:11 24 4
gpt4 key购买 nike

我正在用 C++ 为 Windows 和 Unix 系统编写服务器。

此服务器的一个关键特性是它必须能够随时接收和发送网络数据包。具体来说,服务器不仅必须能够向客户端发送数据以响应他们的消息,而且还能够在推送中异步向他们发送数据包。

在上述场景中,我很难实现使用 select() 函数的解决方案。我目前实现的解决方案根本无法说服我,我认为它可以用更好的模式/解决方案来实现。

我目前有一个专用线程(选择器),它通过监听读取服务器套接字(接受新连接)和连接到服务器的套接字中的事件来执行选择。

这是主要的 select() 循环:

    if((sel_res_ = select(nfds_+1, &read_FDs_, NULL, &excep_FDs_, &sel_timeout)) > 0){
if(FD_ISSET(serv_socket, &read_FDs_)){
//we have to handle a newly connection.
...
if(sel_res_ > 1){
//in addition to the newly connection, there is also some other message incoming on client sockets.
...
}
}else{
//we have to handle incoming messages on client sockets
...
}
}

此解决方案非常适合接收数据并以同步形式响应客户端请求。但是,服务器还必须能够发送异步数据,并在必要时发送推送数据包。

为此,我目前使用单独的线程直接在客户端套接字上执行 send()

这个解决方案不能说服我,我想在选择器线程上集中接收和发送数据包。

主要困难是 select() 本质上是阻塞的,在客户端不发送任何数据包或触发超时之前我无法控制。将超时设置得非常低的解决方案并不能说服我;我认为这是一个简单的解决方案,实际上是在进行主动等待,而且不仅如此,最坏的情况是我会在发送推送数据包之前付出超时的代价。

我想到了一个更“优雅”的解决方案;我认为,会很好用,但只适用于 Unix/Linux 平台。我想使用匿名管道并插入到 select() read_FDs_ 匿名管道读取描述符中。这样,当一个线程想要推送数据时,它会在这个管道上写一些东西,中断 select() 并将控制权返回给选择器,然后选择器可以预先准备将数据发送到客户,而不会浪费大量时间。不幸的是,我认为该解决方案无法在 Windows 上实现,因为该系统上的 select() 函数仅适用于实际上是套接字的 fds。

所以问题是:是否有一些众所周知的解决方案可用于解决这种情况(Linux 和 Windows)?

最佳答案

您可以创建一个自连接的 UDP 套接字,这在 Windows 和 Linux 上同样有效。

基本上,您创建一个 UDP 套接字,bind() 它到 INADDR_LOOPBACK 和端口 0,并且 connect() 它到它自己 (使用从 getsockname() 获取的地址。

此时,您可以向自己发送单字节消息(或更具体的消息)来唤醒自己。

关于c - 推送服务器的 select() 问题 - c/c++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24240780/

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