第一步,创建socket套接字
QuicSocket socket = QuicCreateSocket();
后面是初始化地址 同tcp,udp socket相类似
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(9700);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
第二步 ,绑定
//绑定
res = QuicBind(socket, (struct sockaddr*)&addr, sizeof(addr));
//跟踪一下这个函数
int QuicBind(QuicSocket sock, const struct sockaddr* addr, socklen_t addrlen)
{
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;
}
int res = ((QuicSocketEntry*)socket.get())->Bind(addr, addrlen);
DebugPrint(dbg_api, "sock = %d, return = %d, errno = %d", sock, res, errno);
return res;
}
下面有个检测函数
//下面出现了一个CHECK_RES()函数
#define CHECK_RES(res, api) \
do {\
if (res < 0) {\
perror(api " error");\
return 1;\
}\
} while (0)
//判断绑定是否是成功的,如果绑定失败,则报该类型的错误
第三步 accept()
//函数
QuicSocket QuicSocketAccept(QuicSocket listenSock)
{
auto socket = EntryBase::GetFdManager().Get(listenSock);
if (!socket || socket->Category() != EntryCategory::Socket) {
DebugPrint(dbg_api, "sock = %d, return = -1, errno = EBADF", listenSock);
errno = EBADF;
return -1;
}
auto newSocket = ((QuicSocketEntry*)socket.get())->AcceptSocket();
if (!newSocket) {
DebugPrint(dbg_api, "sock = %d, return = -1, errno = %d", listenSock, errno);
return -1;
}
DebugPrint(dbg_api, "sock = %d, newSocket = %d", listenSock, newSocket->Fd());
return newSocket->Fd();
}
第四步 接受quic stream流
//接收quic流
QuicStream newStream = QuicStreamAccept(fd);
QuicStream QuicStreamAccept(QuicSocket sock)
{
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())->AcceptStream();
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();
}
读取quic stream
//从流中读取数据
OnRead(newStream);
//跟踪这个函数
//int OnRead(QuicStream fd) {
int res;
char buf[10240];
for (;;) {
res = QuicRead(fd, buf, sizeof(buf));
if (res < 0) {
if (errno == EAGAIN)
return 0;
QuicCloseStream(fd);
return 1;
} else if (res == 0) {
QuicStreamShutdown(fd, SHUT_WR);
return 1;
}
UserLog("recv(len=%d): %.*s\n", res, res, buf);
res = QuicWrite(fd, buf, res, false);
CHECK_RES(res, "write");
}
}
//这个函数里面有
QuicRead()和QuicWrite()函数
第五步
关闭套接字和stream流
//关闭socket
QuicCloseSocket(fd);
//关闭流
QuicCloseStream(fd);