網絡編程 epoll

寫下來,免得忘了


CT 5
void nothing(int i)
{
	cerr << "signal: " << i << endl;
}
int main()
{
	int nconn = 0;
	int nacc = 0;
	bool maxconn = false;  

	int n;
	cout << getpid() << endl;
	//signal(SIGINT,nothing); // Ctrl+c
	signal(SIGUSR1,nothing); // kill -10 pid. Test EINTR
	char buf[BUFSIZ];
	struct sockaddr_in addr= {0};
	struct sockaddr_in cli_addr= {0};
	socklen_t cli_len = sizeof cli_addr;

	short port;
	int fd = socket(PF_INET,SOCK_STREAM,0);
	if(fd < 0)
	{
		perror("socket()");
		return 1;
	}


	int flags = fcntl(fd,F_GETFL,0);
	flags |= O_NONBLOCK;
	//fcntl(fd,F_SETFL,flags);

	addr.sin_family = AF_INET;
	//n = inet_aton("127.0.0.1",&addr.sin_addr);
	addr.sin_addr.s_addr = INADDR_ANY;
	addr.sin_port = htons(6219);

	n = bind(fd,(struct sockaddr*) &addr,sizeof(addr));
	if(n < 0)
	{
		perror("bind()");
		return 2;
	}

	n = listen(fd,2);
	if(n < 0)
	{
		perror("listen()");
		return 3;
	}

	vector<int> fdvec;
	fdvec.push_back(fd);

	struct epoll_event ev = {0};
	int kfd = epoll_create(MAX_CONNECT+1);
	if(kfd < 0)
	{
		perror("epoll_create");
		return 4;
	}
	ev.data.fd = fd;
	ev.events = EPOLLIN | EPOLLET;
	n = epoll_ctl(kfd,EPOLL_CTL_ADD,fd,&ev);
	if(n < 0)
	{
		perror("epoll_ctl()");
		return 5;
	}

	while(1)
	{
		struct epoll_event events[20];
		memset(events,0,sizeof events);
		cerr << "epoll_wait..." << "total:" << nconn;
		n = epoll_wait(kfd,events,MAX_CONNECT+1,-1);
		cerr << " Done. "<<n<<endl;
		if(n < 0)
		{
			perror("epoll_wait");
			return 6;
		}
		else if(0 == n)
		{
			cout << "Timeout." << endl;
			continue;
		}
		else
		{
			for(int i=0; i<n; ++i)
			{
				if(events[i].data.fd == fd)
				{ // accept
					int newfd = accept(fd,(struct sockaddr*)&cli_addr,&cli_len);
					cerr << "accept:" << newfd << endl;
					if(newfd < 0)
					{
						perror("accept()");
						return 5;
					}
					ev.data.fd = newfd;
					ev.events = EPOLLIN | EPOLLET;
					epoll_ctl(kfd,EPOLL_CTL_ADD,newfd,&ev);
					if(++nconn >= MAX_CONNECT)
					{
						ev.data.fd = fd;
						epoll_ctl(kfd,EPOLL_CTL_DEL,fd,&ev);
						maxconn = true;
					}

				}
				else if(events[i].events & EPOLLIN)
				{ // read
					char buf[BUFSIZ] = {0};
					int n = read(events[i].data.fd,buf,sizeof(buf));
					cerr << "read " <<n<<"bytes"<<endl;
					if(n < 0)
					{
						perror("read()");
						if(EINTR == errno)
						{
							continue;
						}
						return 6;
					}
					if(0 == n)
					{ // client closed or network down.
						close(events[i].data.fd);
						--nconn;
						if(maxconn)
						{
							maxconn = false;
							ev.data.fd = fd;
							ev.events = EPOLLIN | EPOLLET;
							epoll_ctl(kfd,EPOLL_CTL_ADD,fd,&ev);
						}
						continue;
					}
					int m = write(events[i].data.fd,buf,n);
					if(m < 0)
					{
						perror("write()");
						return 7;
					}
				}
			} // for.
		}

	} //while(1)

	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章