描述符读就绪情况:
1)套接字的读缓冲大于低位标记SO_RECVNOWAT(默认为1)
2) 监听套接字监听到新的连接
3) 套接字接收到了FIN信号,read=0.
4) 套接字出错,read = -1
描述符写就绪情况:
1)套接字的写缓冲大于低位标记SO_SENDNOWAT(默认为2048)
2) 套接字接收到了FIN信号,write=-1,errno= sigpipe。
3) 套接字出错,write=-1
int main(int argc, char **argv) {int ret = 0, fds[FD_SIZE],maxfd,nselect,maxidx,nread,nwrite;
for (int i = 0; i < FD_SIZE; i++) {
fds[i] = -1;
}
//step 1
int listenfd = socket(AF_INET, SOCK_STREAM,0);
_ChkRet(listenfd,socket);
struct sockaddr_in sockAddr, cliaddr;
bzero(&sockAddr,sizeof(sockaddr_in));
sockAddr.sin_port = htons(PORT);
sockAddr.sin_family = AF_INET;
//inet_pton(AF_INET,argv[1],sockAddr.sin_addr
sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
//step 2
ret = bind(listenfd,(struct sockaddr*)&sockAddr,sizeof(struct sockaddr));
_ChkRet(ret,bind);
//step 3
ret = listen(serSock,5);
_ChkRet(ret,listen);
fd_set rset,allset;
FD_ZERO(&allset);
FD_SET(listenfd, &allset);
maxfd = listenfd;
maxidx = 0;
char readbuf[1024], writebuf[1024];
//step 4
while (1) {
rset = allset;
nselect = select(maxfd+1, &rset,NULL,NULL,NULL);
if (FD_ISSET(listenfd, &rset)) {
socklen_t clilen = sizeof(struct sockaddr);
int clifd = accept(listenfd, (struct sockaddr*)&cliaddr, &clilen);
_ChkRet(clifd,accept);
for (int i = 0 ; i < FD_SIZE; i++) {
if (fds[i] == -1) {
fds[i] = clifd;
break;
}
}
if (i == FD_SIZE) {
printf("too many links, refuse.....\n");
continue;
}
FD_SET(clifd, &allset);
if (clifd > maxfd) {
maxfd = clifd;
}
if (i > maxidx) {
maxidx = i;
}
if (--nselect <= 0) {
continue;
}
}
for (int j = 0; j <=maxidx ; j++) {
if (FD_ISSET(fds[j], &rset)) {
if ((nread = read(fds[j],readbuf,1024)) == 0) {
close(fds[j]);
fds[j] = -1;
FD_CLR(fds[j],&allset);
} else {
write(fds[j], "hello world", 10);
}
}
if (--nselect <= 0) {
break;
}
}
}
}