#include <sys/socket.h> int shutdown(int sockfd, int how); - sockfd: 须要关闭的socket的描述符 - how: 容许shutdown操做选择如下几种方式: - SHUT_RD(0): 关闭sockfd上的读功能,该套接字再也不接收数据,任何在套接字接收缓冲区的数据都将被丢弃; - SHUT_WR(1): 关闭sockfd的写功能,进程不能对此套接字发出写操做; - SHUT_RDWR(2): 关闭读写功能,至关于调用shut down两次,首先是SHUT_RD,而后是SHUT_WR. 1. 使用close(),若是多个进程共享一个套接字,close每调用一次,计数减1,直到计数为0,也就是全部进程都调用了close,套接字被释放。 2. 使用shutdown(),在多进程中若是一个进程调用了shutdown(sfd, SHUT_RDWR)后,其余进程将没法通讯。但若是一个进程close(sfd)将不会影响其余进程。
// 设置套接字的属性,包括端口复用 #include <sts/types.h> #include <sys/socket.h> int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen); - sockfd: 要操做的文件描述符 - level: 级别 - SOL_SOCKET(端口复用) - optname: 选项的名称 - SO_REUSEADDR - SO_REUSEPORT - optval: 端口复用的值(整型) - 1: 能够复用 - 0: 不能够复用 - optlen: optval参数的大小,sizeof(optval)
#include <sys/times.h> #include <sys/types.h> #include <unistd.h> int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); // sizeof(fd_set) = 128 byte = 1024 bit - nfds: 委托内核检测的最大文件描述符+1 - readfds: 要检测的文件描述符的读的集合,委托内核检测哪些文件描述符的读属性, - 对应的是对方发送过来的数据, - 为读是被动接收数据,检测的就是读缓冲区 - 是一个传入传出参数 - writefds: 要检测的文件描述符的写的集合,委托内核检测哪些文件描述符的写属性 - 委托内核检测写缓冲区是否还能够写数据 - exceptefds: 检测发生异常的文件描述符的集合 - timeout: 设置的超时时间, NULL 永久阻塞,直到检测到了文件描述符有变化;tv_sec = 0 tv_usec = 0 不阻塞;tv_sec > 0 tv_usec > 0 阻塞对应时间 - 返回值:失败返回-1;成功返回>0(n)的数,表示检测的集合中有n个文件描述符发生了变化 struct timeval { long tv_sec; long tv_usec; } void FD_CLR(int fd, fd_set *set); - 做用:将参数文件描述符fd对应的标志位设置为0 void FD_ISSET(int fd, fd_set *set); - 做用:判断fd对应的标志位是0仍是1, - 返回值:fd对应的标志位的值 void FD_SET(int fd, fd_set *set); - 做用:将参数文件描述符fd对应的标志位设置为1 void FD_ZERO(fd_set *set); - 做用:fd_set一共有1024位,初始化全部位为0
#include <poll.h> struct pollfd { int fd; // 委托内核检测的文件描述符 short events; // 委托内核检测文件描述符的什么事件 POLLIN 读 POLLOUT 写 short revents; // 内核返回的文件描述符发生的事件 }; int poll(struct pollfd *fds, nfds_t nfds, int timeout); - fds: 须要检测的文件描述符的集合 - nfds: 委托内核检测的最大文件描述符+1 - timeout: 阻塞时长, NULL 永久阻塞,-1 阻塞,当检测到须要检测的文件描述符发生变化时解除阻塞;0 不阻塞;>0 阻塞时长 - 返回值:失败返回-1;成功返回>0(n)的数,表示检测的集合中有n个文件描述符发生了变化
#include <sys/epoll.h> int epoll_create(int size); - 做用:建立一个新的epoll实例。在内核中建立一个数据,包括须要检测的文件描述符(RBT),和就绪列表存放检测到数据发生改变的文件描述符信息(双链表) - size: >0, 无心义;之前底层hashmap实现时须要 - 返回值:成功返回文件描述符,操做epoll实例;失败返回-1并设置errno int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); - epfd: epoll实例对应的文件描述符 - op: 要进行什么操做,EPOLL_CTL_ADD 添加;EPOLL_CTL_MOD 修改;EPOLL_CTL_DEL 删除 - fd: 要检测的文件描述符 - event: 检测文件描述符什么事件,常见的epoll检测事件:EPOLLIN、EPOLLOUT、EPOLLERR int epoll_wait(nt epfd, struct epoll_event *events, int maxevents, int timeout); - epfd: epoll实例对应的文件描述符 - events: 传出参数,保存了发生了变化的文件描述符的信息 - maxevents: 第二参数结构体数组的大小 - timeout: 阻塞时长, NULL 永久阻塞,-1 阻塞,当检测到须要检测的文件描述符发生变化时解除阻塞;0 不阻塞;>0 阻塞时长 - 返回值:失败返回-1;成功返回>0(n)的数,表示检测的集合中有n个文件描述符发生了变化