背景:
lsquic官方demo提供一个发送单个消息的示例.
本文介绍基于lsquic api(准确来说是回调函数)发送大文件.
发送大文件和发送单条消息的区别?
发送单条消息不用考虑流控. 而发送大文件需要考虑发送缓冲区满的情况.
发送大文件的实现:
和发送单条消息一样, 发送大文件的逻辑也是在 on_write回调函数里边.
简单处理逻辑如下:
nw = lsquic_stream_writef(stream, &reader);
if (nw > 0)
{
LOG("write bytes: %d\n", nw);
} else if (0 == nw) {
LOG("write bytes: %d\n", nw);
tut->tut_u.c.stream = stream;
ev_timer_stop(tut->tut_loop, &tut->tut_timer_delaysend);
ev_timer_init(&tut->tut_timer, tut_timer_delaysend, 1000, 0.);
ev_timer_start(tut->tut_loop, &tut->tut_timer_delaysend);
lsquic_stream_flush(stream);
lsquic_stream_wantwrite(stream, 0);
}
static void
tut_timer_delaysend (EV_P_ ev_timer *timer, int revents)
{
struct tut *const tut = timer->data;
LOG("delay send\n");
lsquic_stream_wantwrite(tut->tut_u.c.stream, 1);
}
注意事项:
如何判断缓冲区已满?
lsquic_stream_write 返回0的时候缓冲区是满的.
缓冲区满了如何处理?
本文简单处理逻辑是暂定发送, 调用lsquic_stream_wantwrite(stream, 0); 暂停写逻辑, 等待底层发送, 同时启动一个稍后发送的定时器, 定时器的逻辑很简单, 调用lsquic_stream_wantwrite(stream, 1)继续处理应用层发送逻辑.
如果不暂停写, 上层会一直有写事件传给事件调度器, 底层处理不及时的情况. 导致程序报warnning.
如何判断所有数据是否发送完毕?
网友评论