这个必须支持,谁让他宣传的说select是一个标准呢 。
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/time.h>
#include <unistd.h>
int main (int argc, char *argv[])
{
int listenfd, connfd;
struct sockaddr_in serveraddr;
char buff[20];
if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
printf("create error: %s(errno=%d)\n", strerror(errno), errno);
exit(0);
}
memset(&serveraddr, 0, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons(6789);
if(bind(listenfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) == -1)
{
printf("bind error: %s(errno=%d)\n",strerror(errno), errno);
exit(0);
}
if(listen(listenfd, 5) == -1)
{
printf("listen error: %s(errno=%d)\n",strerror(errno), errno);
exit(0);
}
if(fcntl(listenfd, F_SETFL, O_NONBLOCK) == -1)
{
printf("fcntl error: %s(errno=%d)\n",strerror(errno), errno);
exit(0);
}
struct timeval timeout;
timeout.tv_sec = 60;
timeout.tv_usec = 0;
int ret, i = 0;
int maxfd;// = listenfd;
int fds[6] = {0,0,0,0,0,0,0};
fd_set readfd, allfd;
FD_ZERO(&readfd);
FD_SET(listenfd, &allfd);
maxfd = listenfd;
fds[i++] = listenfd;
while(1)
{
readfd = allfd;
ret = select(maxfd + 1, &readfd, NULL, NULL, /*&timeout*/0);
if(ret == -1)
{
printf("select error: %s(errno=%d)\n",strerror(errno), errno);
exit(0);
}
else if(ret == 0)
{
printf("select timeout error: %s(errno=%d)\n",strerror(errno), errno);
exit(0);
}
else
{
if(FD_ISSET(listenfd, &readfd))
{
int connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
if(connfd == -1)
{
printf("accept error: %s(errno=%d)\n",strerror(errno), errno);
}
else
{
if(i > 5)
{
printf("max connect num, close it\n");
close(connfd);
continue;
//exit(0);
}
printf("accept new socket\n");
if(fcntl(connfd, F_SETFL, O_NONBLOCK) == -1)
{
printf("fcntl error:connfd = %d, %s(errno=%d)\n",connfd, strerror(errno), errno);
exit(0);
}
FD_SET(connfd, &allfd);
if(maxfd < connfd)
maxfd = connfd;
fds[i++] = connfd;
}
}
else
{
int k;
for(k = 1; k < 6; k++)
{
// printf("loop k = %d\n", k);
if(FD_ISSET(fds[k], &readfd))
{
int len = recv(fds[k], buff, 20, 0);
if(len == -1)
{
printf("recv error:connfd = %d, %s(errno=%d)\n", connfd,strerror(errno), errno);
exit(0);
}
else if(len == 0)
{
FD_CLR(fds[k], &allfd);
// printf("socket close\n");
close(fds[k]);
fds[k] = 0;
}
else
{
//buff[len] = '\0';
printf("recv data = %s, len = %d\n", buff, len);
memset(buff, 0, 20);
}
}
}
}
printf("one more time.\n");
}
}
for(i = 0; i < 7; i++)
{
if(fds[i] != 0)
close(fds[i]);
}
return 0;
}
client端根前面几个一样。
都说select各种不好,其实总结起来好像就2点:
1. 监控总数由限制
2. 遍历轮训效率低
poll比他好的就是第一点,其实两个在实际使用上可能差不多。