背景:
? ? ? ? ?lsquic官方demo提供一個(gè)發(fā)送單個(gè)消息的示例.
? ? ? ? ?本文介紹基于lsquic api(準(zhǔn)確來(lái)說(shuō)是回調(diào)函數(shù))發(fā)送大文件.
發(fā)送大文件和發(fā)送單條消息的區(qū)別?
????????發(fā)送單條消息不用考慮流控. 而發(fā)送大文件需要考慮發(fā)送緩沖區(qū)滿的情況.
發(fā)送大文件的實(shí)現(xiàn):
? ? ? ? 和發(fā)送單條消息一樣, 發(fā)送大文件的邏輯也是在 on_write回調(diào)函數(shù)里邊.
? ? ? ?簡(jiǎn)單處理邏輯如下:
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);
}
注意事項(xiàng):
? ? ? ? 如何判斷緩沖區(qū)已滿?
? ??????lsquic_stream_write 返回0的時(shí)候緩沖區(qū)是滿的.
? ? ? ? 緩沖區(qū)滿了如何處理?
? ? ? ? 本文簡(jiǎn)單處理邏輯是暫定發(fā)送, 調(diào)用lsquic_stream_wantwrite(stream, 0); 暫停寫(xiě)邏輯,? 等待底層發(fā)送, 同時(shí)啟動(dòng)一個(gè)稍后發(fā)送的定時(shí)器, 定時(shí)器的邏輯很簡(jiǎn)單, 調(diào)用lsquic_stream_wantwrite(stream, 1)繼續(xù)處理應(yīng)用層發(fā)送邏輯.?
? ? ? ?如果不暫停寫(xiě), 上層會(huì)一直有寫(xiě)事件傳給事件調(diào)度器, 底層處理不及時(shí)的情況. 導(dǎo)致程序報(bào)warnning.?
? ? ? ? 如何判斷所有數(shù)據(jù)是否發(fā)送完畢?