posix_quic-master 客户端逻辑分析

最近在学习quic协议,由于是初学阶段,对这套代码的具体实现还不太熟悉,记录一下对客户端的逻辑分析
在posix_quic-master/test/client/src 文件夹

先是创建socket套接字

//建立套接字
//typedef int posix_quic::QuicSocket
//也就是说QuicSocket就是int数据类型
 QuicSocket socket = QuicCreateSocket();
//在quic_socket.cpp文件中  找到QuicCreateSocket()函数
QuicSocket QuicCreateSocket()
{
//auto是自动类型推断关键字
    auto socket = QuicSocketEntry::NewQuicSocketEntry(false);
    DebugPrint(dbg_api, "socket fd = %d", socket->Fd());
    return socket->Fd();
}

第二步是建立connect()连接

//建立udp连接
    res = QuicConnect(socket, (struct sockaddr*)&addr, sizeof(addr)

quic是通过流的方式发送数据 所以创建了quic stream

//创建quic stream
  QuicStream stream = QuicCreateStream(fd);//创建stream流
//跟踪QuicCreateStream()函数
QuicStream QuicCreateStream(QuicSocket sock)
{//auto 变量自动类型推断
    auto socket = EntryBase::GetFdManager().Get(sock);
    if (!socket || socket->Category() != EntryCategory::Socket) {
        DebugPrint(dbg_api, "sock = %d, return = -1, errno = EBADF", sock);
        errno = EBADF;
        return -1;
    }

    auto stream = ((QuicSocketEntry*)socket.get())->CreateStream();
    if (!stream) {
        DebugPrint(dbg_api, "sock = %d, return = -1, errno = %d", sock, errno);
        return -1;
    }

    DebugPrint(dbg_api, "sock = %d, newStream = %d", sock, stream->Fd());
    return stream->Fd();
}
//再跟进CreateStream
QuicStreamEntryPtr QuicSocketEntry::CreateStream()
{
    if (!IsConnected()) {
        errno = ENOTCONN;	/* Transport endpoint is not connected */
        return QuicStreamEntryPtr();
    }

    std::unique_lock<std::recursive_mutex> lock(mtx_);
    QuartcStream* stream = impl_->CreateOutgoingDynamicStream();
    return QuicStreamEntry::NewQuicStream(shared_from_this(), stream);
}

第三步接收和发送数据

//发送数据
 res = QuicWrite(stream, s.c_str(), s.size(), false);
//跟踪一下QuicWrite()函数
ssize_t QuicWrite(QuicStream stream, const void* data, size_t length, bool fin)
{
    /*
    struct iovec
  {
    void *iov_base;	//Pointer to data. 
    size_t iov_len;	//Length of data.  
  };
    
    */
    struct iovec iov;
    iov.iov_base = (void*)data;
    iov.iov_len = length;
    return QuicWritev(stream, &iov, 1, fin);
}

接收数据

//接收数据
 res = QuicRead(fd, buf, sizeof(buf));//读事件
//跟踪一下QuicRead函数
ssize_t QuicRead(QuicStream stream, void* data, size_t length)
{
    struct iovec iov;
    iov.iov_base = data;
    iov.iov_len = length;
    return QuicReadv(stream, &iov, 1);
}
//跟踪一下QuicReadv函数
size_t QuicReadv(QuicStream stream, const struct iovec* iov, int iov_count)
{
    auto streamPtr = EntryBase::GetFdManager().Get(stream);
    if (!streamPtr || streamPtr->Category() != EntryCategory::Stream) {
        DebugPrint(dbg_api, "stream = %d, return = -1, errno = EBADF", stream);
        errno = EBADF;
        return -1;
    }

    ssize_t res = ((QuicStreamEntry*)streamPtr.get())->Readv(iov, iov_count);
    DebugPrint(dbg_api, "stream = %d, return = %ld, errno = %d", stream, res, errno);
    return res;
}

第四步关闭socket连接以及quic stream

//关闭socket连接
   QuicCloseSocket(fd);
//跟踪一下这个函数
int QuicCloseSocket(QuicSocket sock)
{
    EntryPtr entry = EntryBase::GetFdManager().Get(sock);
    if (!entry || entry->Category() != EntryCategory::Socket) {
        DebugPrint(dbg_api, "sock = %d, return = -1, errno = EBADF", sock);
        errno = EBADF;
        return -1;
    }

    auto socket = std::dynamic_pointer_cast<QuicSocketEntry>(entry);
    socket->Close();
    QuicSocketEntry::DeleteQuicSocketEntry(socket);
    DebugPrint(dbg_api, "sock = %d, return = 0", sock);
    return 0;
}
//关闭quic stream
 QuicCloseStream(fd);

客户端逻辑上是这样,后期会仔细跟进细节!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值