close並不是當即關閉一個鏈接,而是將fd的引用數減1。算法
#include<sys/sendfile.h> ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count);
#include<fcntl.h> ssize_t splice(int in_fd, loff_t* off_in, int out_fd, loff_t* off_out, size_t len, unsigned int flags); //使用splice實現零拷貝反射服務器 int pipefd[2]; int ret = pipe(pipefd); ret = splice(connectfd, NULL, pipefd[1], NULL, 65536, SPLICE_F_MORE | SPLICE_F_MOVE); ret = splice(pipefd[0], NULL, connectfd, NULL, 65536, SPLICE_F_MORE | SPLICE_F_MOVE); close(connectfd);
EPOLLONESHOT:對於註冊EPOLLONESHOT事件的文件描述符,操做系統最多觸發其上註冊的一個事件(可讀,可寫或者異常),而且只觸發一次,除非咱們使用epoll_ctl函數重置該文件描述符上註冊的EPOLLONESHOT事件。
```編程
int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, struct timeval* timeout);服務器
FD_ZERO(fd_set* fdset);
FD_SET(int fd, fd_set* fdset);
FD_CLR(int fd,fd_set* fdset);
int FD_ISSET(int fd,fd_set* fdset);網絡
struct timeval
{
long tv_sec; //秒數
long tv_usec; //微秒數
}socket
int poll(struct pollfd* fds, nfds_t nfds, int timeout);函數
struct pollfd
{
int fd;
short event; //註冊的事件
short revent; //實際發生的事件,內核填充,記得每次判斷後歸零
}ui
POLLIN:數據可讀
POLLOUT:數據可寫
POLLREHUP:TCP鏈接被對方關閉,或者對方關閉了寫操做
POLLERR:錯誤
POLLHUP:掛起
POLLNVAL:文件描述符沒有打開操作系統
int epoll_create(int size);
int epoll_ctl(int epollfd, int op, int fd, struct epoll_event* event);
int epoll_wait(int epfd, struct epoll_event* events, int maxevents, int timeout);線程
op參數的類型:
EPOLL_CTL_ADD:向事件註冊表中註冊fd事件
EPOLL_CTL_MOD:修改fd上註冊的事件
EPOLL_CTL_DEL:刪除fd上註冊的事件ssr
struct epoll_event
{
_uint32_t events;
epoll_data_t data;
};
union epoll_data
{
void* ptr;
int fd; //指定事件所從屬的描述符
uint32_t u32;
uint64_t u64;
} epoll_data_t;
- 服務器端處理信號的方式:
void sig_handler(int sig)
{
int save_errno = errno;
int msg = sig;
send(pipefd[1], (char*)&msg, 1, 0);
errno = save_errno;
}
void addsig(int sig)
{
struct sigaction sa;
memset(&sa, '\0', sizeof(sa));
sa.sa_handleer = sig_handler;
sa.sa_flags |= SA_RESTART;
sigfillset(&sa.sa_mask);
assrt(sigaction(sig, &sa, NULL) != -1);
}
```