SimpleTorrent
|
网络连接相关 API 实现 更多...
#include "util.h"
#include "metainfo.h"
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <netdb.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <pthread.h>
结构体 | |
struct | HttpRequest |
描述一个 HTTP 请求 更多... | |
宏定义 | |
#define | REQUEST_MAX 1024 |
HTTP 报文缓冲区的最大长度 | |
函数 | |
void | parse_url (const char *url, char *method, char *host, char *port, char *request) |
解析 url 获取应用层协议、主机名、端口号 更多... | |
struct HttpRequest * | create_http_request (const char *method, const char *host) |
创建一个 HTTP 请求 更多... | |
void | add_http_request_attr (struct HttpRequest *req, const char *key, const char *fmt,...) |
增加一个请求属性 更多... | |
int | send_http_request (struct HttpRequest *req, int sfd) |
发送一个 HTTP 请求 更多... | |
int | make_nonblocking (int sfd) |
将套接字设置成非阻塞的 更多... | |
int | make_blocking (int sfd) |
将套接字设置成阻塞的 更多... | |
int | async_connect (int efd, int sfd, const struct sockaddr *addr, socklen_t addrlen) |
异步 connect 更多... | |
void * | async_connect_to_tracker_non_block (void *arg) |
异步连接线程 更多... | |
void | async_connect_to_tracker (struct Tracker *tracker, int efd) |
异步地与 tracker 建立连接,调用后连接并不立即建立 更多... | |
网络连接相关 API 实现
void add_http_request_attr | ( | struct HttpRequest * | req, |
const char * | key, | ||
const char * | fmt, | ||
... | |||
) |
增加一个请求属性
req | HTTP 请求句柄 |
key | 属性键 |
fmt | ... 属性值 [可格式化] |
int async_connect | ( | int | efd, |
int | sfd, | ||
const struct sockaddr * | addr, | ||
socklen_t | addrlen | ||
) |
异步 connect
efd | epoll 描述符 |
sfd | 连接套接字 |
addr | 连接地址 |
addrlen | 地址结构体长度 |
如果 connect 能够立即完成,直接返回;否则,将描述符加入 epoll, 侦听 EPOLLOUT 事件,同时要关注 EPOLLERR 和 EPOLLHUP 处理实际错误。
void async_connect_to_tracker | ( | struct Tracker * | tracker, |
int | efd | ||
) |
异步地与 tracker 建立连接,调用后连接并不立即建立
tracker | 指向 tracker 信息的指针 |
efd | epoll file descriptor,创建的套接字会加入该队列中,侦听 EPOLLOUT |
void* async_connect_to_tracker_non_block | ( | void * | arg | ) |
异步连接线程
本函数主要是为了规避 getaddrinfo 的阻塞,一个重要的隐含前提是通过 tracker 的 sfd 来传递 efd。 毕竟 sfd 作为连接套接字在调用时是没有意义的。
arg | 实际上是指向 tracker 的指针 |
struct HttpRequest* create_http_request | ( | const char * | method, |
const char * | host | ||
) |
创建一个 HTTP 请求
method | 请求方法, 主要用 GET |
host | 主机名 |
int make_blocking | ( | int | sfd | ) |
将套接字设置成阻塞的
sfd | 套接字 |
int make_nonblocking | ( | int | sfd | ) |
将套接字设置成非阻塞的
sfd | 套接字 |
void parse_url | ( | const char * | url, |
char * | method, | ||
char * | host, | ||
char * | port, | ||
char * | request | ||
) |
解析 url 获取应用层协议、主机名、端口号
解析 URL
url | 指向 url 字符串 |
method | 接收应用层协议名 |
host | 接收主机名 |
port | 接收端口号 |
request | http 请求路径,一般是 /announce |
自行保证缓冲区大小,host 和 port 可以使用 NI_MAXHOST 和 NI_MAXSERV. method 一般是 http 或者 udp.
int send_http_request | ( | struct HttpRequest * | req, |
int | sfd | ||
) |
发送一个 HTTP 请求
req | HTTP 请求句柄 |
sfd | 连接套接字 |