- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要获得同步 I/O 但具有以下特性:
因此,我使用来自 Boost.Asio 的异步 I/O 并通过 boost::asio::io_context::run_one_for() 执行它。有一个这样实现解析、连接、读写的例子。
long const DefaultTimeout = 50;
namespace asio = boost::asio;
using boost::asio::ip::tcp;
template <typename T>
void PerformIO(T &Object, long Timeout)
{
auto &Context = Object.get_executor().context();
Context.reset();
if (!Context.run_one_for(std::chrono::seconds(Timeout)))
throw std::exception("I/O operation was timed out");
}
template <typename T, typename TSuccessFlag>
void PerformIO(T &Object, long Timeout, TSuccessFlag &Success)
{
PerformIO(Object, Timeout);
boost::this_thread::interruption_point();
if (!Success)
throw std::exception("I/O operation was not successful");
}
tcp::resolver::results_type Resolve(tcp::resolver &Resolver, std::string const &Host, std::string const &Port)
{
bool Resolved = false;
tcp::resolver::results_type Endpoints;
Resolver.async_resolve(Host, Port,
[&](boost::system::error_code const &Error, boost::asio::ip::tcp::resolver::results_type Results){ Endpoints = Results; Resolved = true; });
PerformIO(Resolver, DefaultTimeout, Resolved);
if (Endpoints.begin() == Endpoints.end())
throw std::exception("Not resolved");
return Endpoints;
}
template <typename T>
void Connect(tcp::socket &Socket, T const &Endpoints)
{
bool Connected = false;
asio::async_connect(Socket, Endpoints,
[&](boost::system::error_code const &Error, boost::asio::ip::tcp::endpoint const &Endpoint){ Connected = true; });
PerformIO(Socket, DefaultTimeout, Connected);
}
template <typename T>
size_t ReadSome(tcp::socket &Socket, T &Buffers)
{
size_t Bytes = 0;
asio::async_read(Socket, Buffers, asio::transfer_at_least(1),
[&](boost::system::error_code const &Error, std::size_t BytesTransferred){ Bytes += BytesTransferred; });
PerformIO(Socket, DefaultTimeout, Bytes);
return Bytes;
}
template <typename T>
size_t Write(tcp::socket &Socket, T &Buffers)
{
size_t Bytes = 0;
asio::async_write(Socket, Buffers,
[&](boost::system::error_code const &Error, std::size_t BytesTransferred){ Bytes += BytesTransferred; });
PerformIO(Socket, DefaultTimeout, Bytes);
return Bytes;
}
它适用于小数据,但如果我尝试像这样发送大数据缓冲区,它就会失败:
// tcp::socket Socket;
// char const *Buffer;
// size_t BufferSize = 1000000;
Write(Socket, asio::buffer(Buffer, BufferSize))
我认为原因是 boost::asio::io_context::run_one_for() 的实现。就是这样( boost 1.67):
template <typename Rep, typename Period>
std::size_t io_context::run_one_for(
const chrono::duration<Rep, Period>& rel_time)
{
return this->run_one_until(chrono::steady_clock::now() + rel_time);
}
template <typename Clock, typename Duration>
std::size_t io_context::run_one_until(
const chrono::time_point<Clock, Duration>& abs_time)
{
typename Clock::time_point now = Clock::now();
while (now < abs_time)
{
typename Clock::duration rel_time = abs_time - now;
if (rel_time > chrono::seconds(1))
rel_time = chrono::seconds(1);
boost::system::error_code ec;
std::size_t s = impl_.wait_one(
static_cast<long>(chrono::duration_cast<
chrono::microseconds>(rel_time).count()), ec);
boost::asio::detail::throw_error(ec);
if (s || impl_.stopped())
return s;
now = Clock::now();
}
return 0;
}
注意 1 秒的限制。我认为发送大缓冲区需要超过 1 秒并且执行停止。我可以按 64k 字节顺序执行 Write()
并且它有效。但我认为如果连接无法每秒发送 64k 字节,它将失败。所以,我需要一个更好的解决方案。
最佳答案
I think the reason is the implementation of boost::asio::io_context::run_one_for(). There it is (boost 1.67):
没有。原因是 boost::asio::[async_][read|write][_.*]
是组合操作。 run_one[_*]
仅运行单个处理程序,因此它不会完成组合的异步操作。
另请注意,boost::asio::write
是一个同步操作,与周围的任何逻辑无关,因此您的超时甚至不会起作用。
您可以将异步操作包装在本地 io_context 中并使用截止日期运行它直到完成(因此,run_for
而不是 run_one_for
)。
您可以从 How to simulate boost::asio::write with a timeout 中收集到类似的概念。 - 尽管使用 run_for(...)
而不是 run_one()
严格(很多)更好(出于上面解释的原因。当时我写道另一个答案 run_for()
不存在,我可能不得不更新那个答案,因为那时我可能错过了组合操作的问题)。
关于c++ - boost::asio::io_context::run_one_for() 无法发送大缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51878733/
这个问题在这里已经有了答案: Possible to make an event handler wait until async / Promise-based code is done? (2
我经常有多个运行的进程(R,Python,eshell/shell),对于每个进程,我经常都有一个相关的脚本,可以从中发送摘要。为此,我通常将每个框架垂直地分成两个窗口,以便脚本文件(例如.py)位于
如何修改 emacs 在关闭缓冲区后选择要显示的缓冲区的方式? 当我有多个列显示相同的缓冲区,然后在其中一个缓冲区中打开另一个文件,然后关闭新打开的缓冲区时,它不会切换回前一个缓冲区,而是切换到另一个
如何将 ex 命令复制到剪贴板或粘贴到缓冲区? 在 Windows 上使用 gvim。 最佳答案 windows剪贴板可以通过the buffer + 访问.因此,可以使用 + 将剪贴板粘贴为前命令。
在 javascript 中如何以比以下更简单的方式获取 b 缓冲区? var num=6553599 var a = new Buffer(4); a.writeInt32LE(num)
每次我在 Google 上搜索有关 OpenGL 编程的文章时,我都会找到一些文章,但似乎所有文章都提到了着色器和缓冲区。那些是什么?你能解释其中的一些吗: 深度缓冲区 模板缓冲区 像素着色器 帧缓冲
我有java考试,当我学习时,我看到了这个练习,我尝试解决它,但我发现一些困难,所以请帮助我考虑实用程序中方法的以下注释、 header 和部分代码名为 Atbash 的加密类。 /**
每次我在 Google 上搜索有关 OpenGL 编程的文章时,我都会找到一些文章,但似乎所有文章都提到了着色器和缓冲区。那些是什么?你能解释其中的一些吗: 深度缓冲区 模板缓冲区 像素着色器 帧缓冲
对于每个属性使用跨步顶点缓冲区与紧密打包缓冲区有何优缺点?我的意思是例如: 步幅:xyzrgb xyzrgb xyzrgb 紧:xyzxyzxyz rgbrgbrgb 乍一看,使用步幅时您似乎可以轻松
我正在尝试将文本文件中每行的数字读取到 ArrayList 中。当我执行以下函数时,它总是跳过最后一个元素。有人可以帮我吗?因为我在这里没有遇到问题,因为它读取直到缓冲区为空,所以他应该在到达 Fil
#include #include int main () { time_t time_raw_format; struct tm * ptr_time; char *buff
基本上我有一个包含不同类型数据的自定义结构。例如: typedef struct example_structure{ uint8_t* example_1[4]; int example_2[4];
我之前的列表实现是一个简单的 LinearLayout,位于一个装满我的项目的 ScrollView 中。 我切换到 ListView 的 Android 实现以简单地使用 CursorAdapter
我想创建一个可变长度的输入事件窗口/缓冲区,当它接收到额外的事件时会变长。 这是为了实现“键入时搜索”功能。我想捕获点击,但为了不给服务器造成压力,我想明智地进行服务调用。 我想到的逻辑是缓冲击键,从
我想将 yuv420P 像素写入缓冲区而不是二进制文件。假设我在指针中存储了 luma 、 Cb 和 Cr。 luma = output_pixel.luma; cb = output_pixel.c
我想在 Go 中构建一个支持多个并发读取器和一个写入器的缓冲区。所有写入缓冲区的内容都应由所有读者读取。允许新读者随时加入,这意味着已经写入的数据必须能够为迟到的读者回放。 缓冲区应满足以下接口(in
本文转载自微信公众号「小明菜市场」,作者小明菜市场。转载本文请联系小明菜市场公众号。 前言 Java NIO 需要理解的主要有缓冲区,通道,选择器,这三个主要的部分。 基础
一 点睛 NIO,可以称为 New IO 或 Non Blocking IO,是在 JDK 1.4 后提供的新 API。传统的I/O 是阻塞式的 I/O、面向流的操作;而 NIO 是非阻塞 I/O 、
我正在寻找一种切换到包含搜索文本的缓冲区的方法。 例如。如果我打开了 100 个缓冲区,我想切换到一个包含 'fooBar = 1' 的缓冲区 最佳答案 我写了一个 Vim 插件来做到这一点:buff
我正在尝试将提取的视频帧(我使用 ffmpeg)推送到 FFMPEG 缓冲区中。我已经查看了 ffmpeg 的缓冲区源文件,例如 buffersrc.c 和 fifo.c,以确定我是否可以这样做,但我
我是一名优秀的程序员,十分优秀!