前言:
此刻你们对“socket select 返回0”大概比较注重,朋友们都需要剖析一些“socket select 返回0”的相关文章。那么小编同时在网上收集了一些有关“socket select 返回0””的相关内容,希望大家能喜欢,小伙伴们快快来了解一下吧!int select(int nfds, readfds, writefds, exceptfds, timeou);
nfds:linux上的socket也叫做fd,将这个参数的值设置为所需要使用select函数检测事件的fd中的最大值加1
readfds: 需要监听可读事件的fd集合
writefds: 需要监听可写事件的fd集合
exceptfds: 需要监听异常事件的fd集合
timeouts:超时时间,即在这个参数设定的时间内检测这些fd的事件,超过事件后,select函数理解返回
select 用于检测在一组socket中是否有事件就绪
读事件就绪
1、 在socket内核中,接收缓冲区中的字节数大于或等于低水位标记SO_RCVLOWAT,此时调用recv或read函数可以无阻塞的读该文件描述符,并且返回值大于0。
2、TCP连接的对端关闭连接,此时本端调用recv或read函数对socket进行读操作, recv或read函数会返回0值。
3、在监听socket上有新的连接请求。
4、在socket上有未处理的错误。
写事件就绪
1、在socket内核中,发送缓冲区中的可用字节数大于或等于低水位标记SO_SNDLOWAT,可用无阻塞的写,并且返回值大于0。
2、socket的写操作被关闭时,对一个写操作被关闭的socket进行写操作,会触发SIGPIPE信号。
3、socket使用非阻塞connect连接成功或失败时。
异常事件就绪
需要在fd_set中删除一个fd,即将对应的bit置0,则可用使用FD_CLR。 void FD_CLR(int fd, fd_set *set)。
需要在fd_set中清除所有fd,即将所有的bit置0,则可用使用FD_ZERO。 void FD_ZERO(fd_set *set)。
FD_ISSET宏判断在某个fd中是否有我们关心的事件。int FD_ISSET(int td, fd_set *set).
#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include <unistd.h>#include <iostream>#include <string.h>#include <sys/time.h>#include <vector>#include <error.h> #define INVALID_FD -1// int select(int nfds, readfds, writefds, exceptfds, timeou);// nfds:linux上的socket也叫做fd,将这个参数的值设置为所需要使用select函数检测事件的fd中的最大值加1// readfds: 需要监听可读事件的fd集合// writefds: 需要监听可写事件的fd集合// exceptfds: 需要监听异常事件的fd集合// timeouts:超时时间,即在这个参数设定的时间内检测这些fd的事件,超过事件后,select函数理解返回// select 用于检测在一组socket中是否有事件就绪// 读事件就绪// 1、 在socket内核中,接收缓冲区中的字节数大于或等于低水位标记SO_RCVLOWAT,此时调用recv或read函数可以无阻塞的读该文件描述符,并且返回值大于0。// 2、TCP连接的对端关闭连接,此时本端调用recv或read函数对socket进行读操作, recv或read函数会返回0值。// 3、在监听socket上有新的连接请求。// 4、在socket上有未处理的错误。// 写事件就绪// 1、在socket内核中,发送缓冲区中的可用字节数大于或等于低水位标记SO_SNDLOWAT,可用无阻塞的写,并且返回值大于0。// 2、socket的写操作被关闭时,对一个写操作被关闭的socket进行写操作,会触发SIGPIPE信号。// 3、socket使用非阻塞connect连接成功或失败时。// 异常事件就绪// 需要在fd_set中删除一个fd,即将对应的bit置0,则可用使用FD_CLR。 void FD_CLR(int fd, fd_set *set)。// 需要在fd_set中清除所有fd,即将所有的bit置0,则可用使用FD_ZERO。 void FD_ZERO(fd_set *set)。// FD_ISSET宏判断在某个fd中是否有我们关心的事件。int FD_ISSET(int td, fd_set *set).int main(){ // create socket int listenfd = socket(AF_INET, SOCK_STREAM, 0); if (listenfd == INVALID_FD) { std::cout << "create listen socket error." << std::endl; return -1; } // init server address struct sockaddr_in bindaddr; bindaddr.sin_family = AF_INET; bindaddr.sin_addr.s_addr = htonl(INADDR_ANY); bindaddr.sin_port = htons(3000); if (bind(listenfd, (struct sockaddr*)&bindaddr, sizeof(bindaddr)) == -1) { std::cout << "bind listen socket error" << std::endl; close(listenfd); return -1; } if (listen(listenfd, SOMAXCONN) == -1) { std::cout << "listen error" << std::endl; close(listenfd); return -1; } std::vector<int> clientfds; int maxfd; while (true) { fd_set readset; FD_ZERO(&readset); FD_SET(listenfd, &readset); maxfd = listenfd; int clientfdslength = clientfds.size(); for (int i = 0; i < clientfdslength; ++i) { if (clientfds[i] != INVALID_FD) { FD_SET(clientfds[i], &readset); if (maxfd < clientfds[i]) { maxfd = clientfds[i]; } } } timeval tm; tm.tv_sec = 1; tm.tv_usec = 0; int ret = select(maxfd + 1, &readset, NULL, NULL, &tm); if (-1 == ret) { if (errno != EINTR) { std::cout << "error: " << errno << std::endl; break; } } else if (0 == ret) { continue; } else { if (FD_ISSET(listenfd, &readset)) { struct sockaddr_in clientaddr; socklen_t clientaddrlen = sizeof(clientaddr); int clientfd = accept(listenfd, (struct sockaddr*)&clientaddr, &clientaddrlen); if (clientfd == INVALID_FD) { std::cout << "clientfd == INVALID_FD" << std::endl; break; } std::cout << "accept a client connection, fd:" << clientfd << std::endl; clientfds.push_back(clientfd); } else { char recvbuf[64]; int clientfdslength = clientfds.size(); for (int i = 0; i < clientfdslength; ++i) { if (clientfds[i] != INVALID_FD && FD_ISSET(clientfds[i], &readset)) { memset(recvbuf, 0, sizeof(recvbuf)); int length = recv(clientfds[i], recvbuf, 64, 0); if (length <= 0) { std::cout << "recv data error, clientfd:" << clientfds[i] << std::endl; close(clientfds[i]); clientfds[i] == INVALID_FD; continue; } std::cout << "clientfd: " << clientfds[i] << ", recv data: " << recvbuf << std::endl; } } } } } int clientfdslength = clientfds.size(); for (int i = 0; i < clientfdslength; ++i) { if(clientfds[i] != INVALID_FD) { close(clientfds[i]); } } std::cout << "end" << std::endl; close(listenfd); return 0;}