使用boost:asio和select?阻止TCP输入或文件更新
using boost:asio with select? blocking on TCP input OR file update
我本来打算在程序中有一个线程,它将等待两个文件描述符,一个用于套接字,另一个用于描述文件系统的FD(特别是等待是否将新文件添加到目录中)。由于我希望很少看到添加的新文件或传入的新TCP消息,我希望有一个线程等待输入,并在发生输入时处理检测到的任何输入,而不是用单独的线程来处理。
然后(终于!)我得到了"老板"的许可,可以使用boost。所以现在我想用boost:asio替换基本的插座。只是我遇到了一个小问题。它似乎实现了它自己的select版本,而不是提供一个我可以直接与select一起使用的FD。这让我无法确定如何在新文件和TCP输入这两个条件下进行阻止,同时一个条件只能使用select,另一个条件似乎不支持使用select。我错过的这件事有什么简单的解决办法吗?
ASIO最好异步使用(这就是它的含义):您可以为TCP读取和文件描述符活动设置处理程序,并且会为您调用处理程序。
下面是一个演示示例(为支持inotify的Linux编写):
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <sys/inotify.h>
namespace asio = boost::asio;
void start_notify_handler();
void start_accept_handler();
// this stuff goes into your class, only global for the simplistic demo
asio::streambuf buf(1024);
asio::io_service io_svc;
asio::posix::stream_descriptor stream_desc(io_svc);
asio::ip::tcp::socket sock(io_svc);
asio::ip::tcp::endpoint end(asio::ip::tcp::v4(), 1234);
asio::ip::tcp::acceptor acceptor(io_svc, end);
// this gets called on file system activity
void notify_handler(const boost::system::error_code&,
std::size_t transferred)
{
size_t processed = 0;
while(transferred - processed >= sizeof(inotify_event))
{
const char* cdata = processed
+ asio::buffer_cast<const char*>(buf.data());
const inotify_event* ievent =
reinterpret_cast<const inotify_event*>(cdata);
processed += sizeof(inotify_event) + ievent->len;
if(ievent->len > 0 && ievent->mask & IN_OPEN)
std::cout << "Someone opened " << ievent->name << 'n';
}
start_notify_handler();
}
// this gets called when nsomeone connects to you on TCP port 1234
void accept_handler(const boost::system::error_code&)
{
std::cout << "Someone connected from "
<< sock.remote_endpoint().address() << 'n';
sock.close(); // dropping connection: this is just a demo
start_accept_handler();
}
void start_notify_handler()
{
stream_desc.async_read_some( buf.prepare(buf.max_size()),
boost::bind(¬ify_handler, asio::placeholders::error,
asio::placeholders::bytes_transferred));
}
void start_accept_handler()
{
acceptor.async_accept(sock,
boost::bind(&accept_handler, asio::placeholders::error));
}
int main()
{
int raw_fd = inotify_init(); // error handling ignored
stream_desc.assign(raw_fd);
inotify_add_watch(raw_fd, ".", IN_OPEN);
start_notify_handler();
start_accept_handler();
io_svc.run();
}
相关文章:
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 2D数组来自文本输入,中间有空格
- 如何使用 < 和 > 命令获取 c++ 中的输入和输出?
- 检查输入是否不是整数或数字
- 正在尝试了解输入验证循环
- 读取文件并输入到矢量中
- C++如何通过用户输入删除列表元素
- 用c++从输入文件中读取另一行
- 读取文件的最后一行并输入到链接列表时出错
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 如何使用用户输入在C++中正确填充2D数组
- C++MySQL C api用户输入行
- 输入到文件并输出到另一个文件,并将流文件传递给函数
- 用户定义函数中的指针和输入
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- 如何在C++中终止具有键盘输入的侦听 TCP 服务器
- SIEM通过TCP流式传输,将多条消息输入一个事件中
- 使用boost:asio和select?阻止TCP输入或文件更新
- 为什么boost::asio::ip::tcp::iostream解析输入?
- 创建一个控制台应用程序,打开TCP/IP连接并用C++、C#或Java打印输入的字符串