文章目录
article
网络接口
AI文章摘要
qwen-turbo-latest
加载中...
1. sys/socket.h
1.1 数据结构
//sockaddr是一个bind默认接受的地址结构体,使用其他地址结构需要强转
struct sockaddr {
sa_family_t sa_family;
char sa_data[14];
}
//sockaddr_un记录本地套接字地址,本地套接字和IP套接字的区别只有地址的不同
struct sockaddr_un {
__kernel_sa_family_t sun_family; /* AF_UNIX 协议簇,本地通信使用AF_UNIX*/
char sun_path[UNIX_PATH_MAX]; /* pathname socket伪文件名,若文件不存在会自动创建*/
};
//sockaddr_in记录IPv4套接字地址
struct sockaddr_in {
__kernel_sa_family_t sin_family; /* Address family 协议粗,IPv4通信使用AF_INET*/
__be16 sin_port; /* Port number 大端存储的short变量,表示一个端口. 需要使用htons将小端数转为大端*/
/*struct in_addr {__be32 s_addr;}*/
struct in_addr sin_addr; /* Internet address 大端存储的的int变量,表示一个IPv4地址,需要使用htonl将小端数转为大端 */
/* Pad to size of `struct sockaddr'. 一个数组*/
unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) - sizeof(unsigned short int) - sizeof(struct in_addr)];
};
//sockaddr_in6记录v6套接字地址
struct sockaddr_in6 {
unsigned short int sin6_family; /* AF_INET6 协议簇,IPv6通信使用AF_INET6*/
__be16 sin6_port; /* Transport layer port # 大端存储的short变量,表示一个端口*/
__be32 sin6_flowinfo; /* IPv6 flow information */
/*
struct in6_addr {
union {
__u8 u6_addr8[16];
#if __UAPI_DEF_IN6_ADDR_ALT
__be16 u6_addr16[8];
__be32 u6_addr32[4];
#endif
}
*/
struct in6_addr sin6_addr; /* IPv6 address 大端存储的128位整形变量,表示一个地址*/
__u32 sin6_scope_id; /* scope id (new in RFC2553) */
};
//arpa/inet.h是配合IP协议使用的一个工具库
uint32_t htonl(uint32_t hostlong) //小端长整形转大端长整形
uint16_t htons(uint16_t hostshort) //小端短整形转大端短整形
uint32_t ntohl(uint32_t netlong) //大端长整形转小端长整形
uint16_t ntohs(uint16_t netshort) //大端短整形转小端短整形
int inet_pton( //点分十进制IP地址转大端int整形,使用dst传出
int af,
const char *src,
void *dst)
const char *inet_ntop( //大端int整形转点分十进制字符串
int af,
const void *src,
char *dst,
socklen_t size)
待验证条目:
- socket的半关闭shutdown close的区别
- socket的状态
socket注意事项: - read未读取足够的数据时阻塞
- write缓存已满时阻塞
1.2 函数
int socket( //获取socket文件描述符,返回socket文件描述符
int domain, //IPv4使用AF_INTE, IPv6使用AF_INET6
int type, //SOCK_STREAM SOCK_DGRAM SOCK_RAW
int protocol) //0
int bind( //将socket绑定到本地地址, 服务器需要调用该函数, 客户端可以不调用connect时会隐式调用, 总之一个socket必须绑定一个地址. 成功返回0, 失败返回-1设置errno
int sockfd, //socket文件描述符
const struct sockaddr *addr, //sockaddr结构体指针
socklen_t addrlen) //addr结构体的长度
int listen( //将套接字设为监听状态
int sockfd, //socket文件描述符
int backlog): //同时连接到该socket的最大连接数
int accept( //阻塞等待客户端的连接请求, 套接字必须为Listen状态。返回与客户端通信的socket文件描述符
int sockfd, //socket文件描述符
struct sockaddr *restrict addr, //sockaddr结构体指针(客户端地址)
socklen_t *restrict addrlen) //addr结构体长度(函数内部可能修改该值所以传指针)
int connect( //连接,返回与服务器通信的socket文件描述符
int sockfd, //socket文件描述符
const struct sockaddr *addr, //sockaddr结构体指针
socklen_t addrlen) //addr结构体长度
ssize_t send(
int sockfd,
const void *buf,
size_t len,
int flags)
ssize_t sendto(
int sockfd,
const void *buf,
size_t len,
int flags,
const struct sockaddr *dest_addr,
socklen_t addrlen)
ssize_t recvfrom(
int sockfd, void *buf, size_t len,
int flags,
struct sockaddr *src_addr,
socklen_t *addrlen)
ssize_t recv(
int sockfd,
void *buf,
size_t len,
int flags)
int getsockopt(
int sockfd, int level,
int optname,
void *optval,
socklen_t *optlen);
int setsockopt( //需要在bind函数前调用
int sockfd,
int level,
int optname,
const void *optval,
socklen_t optlen)
-
2. sys/select.h
2.1 数据结构
2.2 成员函数
int select(
int nfds,
fd_set *readfds,
fd_set *writefds,
fd_set *exceptfds,
struct timeval *timeout)
void FD_CLR(int fd, fd_set *set);
int FD_ISSET(int fd, fd_set *set);
void FD_SET(int fd, fd_set *set);
void FD_ZERO(fd_set *set);
3. poll.h
3.1 数据结构
3.2 成员函数
int poll(
struct pollfd *fds,
nfds_t nfds,
int timeout);
4. sys/epoll.h
4.1 数据结构
struct epoll_event {
uint32_t events; /* Epoll events 是一个位图, EPOLLIN: 当读缓冲区有数据时返回; EPOLLOUT: 当写缓冲区可写时返回 EPOLLET:设置边缘触发. 设置边缘触发后,EPOLLIN表现为客户端发数据才触发,EPOLLOUT表现为缓冲区从满到空闲时触发*/
epoll_data_t data; /* User data variable 一个联合体,看成int则可以存放一个文件描述符,看成void*可以将文件描述符信息存于结构体*/
};
typedef union epoll_data {
void *ptr;
int fd;
uint32_t u32;
uint64_t u64;
} epoll_data_t;
4.2 函数
int epoll_create(int size) //创建epool句柄, 预估规模, 若节点个数超过改值, epoll内部也会自动更改
int epoll_ctl(
int epfd, // epoll树根节点(epoll_create返回值)
int op, //EPOLL_CTL_ADD: 添加节点 EPOLL_CTL_MOD: 修改节点 EPOLL_CTL_DEL: 删除节点
int fd, //文件描述符
struct epoll_event *event) //epoll_event结构体指针, 记录socket文件描述符的信息.
int epoll_wait( //返回events中存储的event个数
int epfd, //epoll树的根节点
struct epoll_event *events, //当epoll检测到改动时会将改动socket的event结构体写到该参数中.
int maxevents, //events数组的最大容量
int timeout) //