使用chroimum QUIC构建QUIC客户端程序
2020年4月22日
我将QUIC异步使用的方法整理了一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
//下面是要用到的一个变量的声明: QuicConnection *conn; QuicTransportClientSession *session; QuicTransportStream *stream; QuicChromiumPacketWriter* writer; //传输会话回调, 会话回调, 流回调 QuicTransportClientSession::ClientVisitor* cv; //OnCanRead, OnFinRead, OnCanWrite QuicSession::Visitor* sev; //OnConnectionClosed, OnWriteBlocked, OnRstStreamReceived, OnStopSendingReceived QuicTransportStream::Visitor *sv; // OnCanRead,OnFinRead,OnCanWrite QuicChromiumPacketReader* reader; QuicChromiumPacketReader::Visitor *rv;//OnReadError,OnPacket base::Thread *thread; SingleThreadTaskRunner *runner; |
第一步: SOCKET连接
1 2 3 |
DatagramClientSocket socket; socket->UseNonBlockingIO(); socket->Connect(dest); |
第二步: 设置SOCKET读写包处理器
1 2 3 4 5 6 7 8 9 10 11 12 |
//设置SOCKET缓冲区 socket->SetReceiveBufferSize(); socket->SetDoNotFragment(); socket->SetSendBufferSize(); //设置socket写(序列化) writer = new QuicChromiumPacketWriter(socket); conn = new QuicConnection(dest, writer); //设置socket读(反序列化) reader = new QuicChromiumPacketReader(socket, rv); reader->startReading(); |
第三步:创建QUIC会话并握手连接
1 2 3 4 5 6 7 8 9 10 11 12 |
//初始化会话, 会话回调和数据回调 session = new QuicTransportClientSession(conn, socket, sev, cv); session_->Initialize(); //会话连结 session_->CryptoConnect(); //注意异步: 连接成功后cv的OnSessionReady会被调用 QuicTransportClientSession::ClientVisitor::OnSessionReady() { stream = session->OpenOutgoingBidirectionalStream(); stream->setVisitor(v); //设置stream回调 } |
第四步: 实现相关回调
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
//stream上有可读消息 QuicTransportStream::Visitor::OnCanRead() { while(true) { n = stream->Read(buffer); if (n <= 0) { break; } } } //stream上有FIN消息 QuicTransportStream::Visitor::OnFinRead() { } //stream上可写 QuicTransportStream::Visitor::OnCanWrite() { } //session关闭的回调 QuicSession::Visitor::OnConnectionClosed() { } //session写阻塞回调 QuicSession::Visitor::OnWriteBlocked() { } //session被重置 QuicSession::Visitor::OnRstStreamReceived() { conn->CloseConnection(); } //session停止发送回调 QuicSession::Visitor::OnStopSendingReceived() { } //writer上reader回调 //QuicChromiumPacketReader::Visitor QuicChromiumPacketReader::Visitor::OnReadError() { conn->CloseConnection(); } //有Packet到来 QuicChromiumPacketReader::Visitor::OnPacket() { conn->ProcessUdpPacket(); } |
第五步:开启一个线程进行异步操作
1 2 3 |
thread = new base::Thread(); thread->StartWithOptions(); runner = thread->task_runner(); |
第六步:设计API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
//创建连接 raw_quic_create(url, verify) { // } //连接 raw_quic_connect(timeout) { runner->PostTask( { do_connect(timeout); } ); return size; } //发送 raw_quic_send(buffer, size) { buf = alloc_copy(buffer, size); runner->PostTask( { append(buf, size); do_send(); } ); return size; } //接收 raw_quic_recv(buffer, size, timeout) { runner->PostTask( { do_recv(buffer, size, timeout); } ); } //关闭 raw_quic_close() { runner->PostTask( { do_close(); } ); return size; } |
有不对的地方欢迎大家指正:nie950 at gmail dot net
分类: C/C++