int main(int argc, char *argv[]){
	if(argc <= 2){
		printf("usage: %s ip_address port_number\n", basename(argv[0]));
		return 1;
	}
	const char* ip = argv[1];
	int port = atoi(argv[2]);
	
	struct sockaddr_in address;
	bzero(&address, sizeof(address));
	address.sin_family = AF_INET;
	inet_pton(AF_INET, ip, &address.sin_addr);
	address.sin_port = htons(port);
	
	int listenfd = socket(PF_INET, SOCK_STREAM, 0);
	assert(listenfd >= 0);
	
	int ret = bind(listenfd, (struct sockaddr*)&address, sizeof(address));
	assert(ret != -1);
	
	ret = listen(listenfd, 5);
	assert(ret != -1);
	
	epoll_event events[MAX_EVENT_NUMBER];
	int epollfd = epoll_create(5);
	assert(epollfd != 0);
	addfd(epollfd, listenfd);
	
	ret = socketpair(PF_UNIX, SOCK_STREAM, 0, pipefd);
	assert(ret != -1);
	setnonblocking(pipefd[1]);
	addfd(epollfd, pipefd[0]);
	
	/*设置信号处理函数*/
	addsig(SIGALARM);
	addsig(SIGTERM);
	bool stop_server = false;
	
	client_data* users = new client_data[FD_LIMIT];
	bool timeout = false;
	alarm(TIMESLOT); /*定时*/
	
	while(!stop_server){
		int number = epoll_wait(epollfd, events, MAX_EVENT_NUMBER, -1);
		if(number < 0 && errno != EINTR){
			printf("epoll failed\n");
			break;
		}
		for(int i = 0; i < number; i++){
			int sockfd = events[i].data.fd;
			if(sockfd == listenfd){
				struct sockaddr_in client_address;
				socklen_t client_addrlength = sizeof(client_address);
				int connfd = accept(sockfd, (struct sockaddr*)&client_address, &client_addrlength);
				addfd(epollfd, connfd);
				
				users[connfd].address = client_address;
				users[connfd].sockfd = connfd;
				util_timer* timer = new util_timer;
				timer->client_data = users[connfd];
				timer->cb_func = cb_func;
				time_t cur = time(NULL);
				timer->expire = cur + 3*TIMESLOT;
				users[connfd].timer = timer;
				timer_lst.add_timer(timer);
			} else if((sockfd == pipefd[0]) && (events[i].events & EPOLLIN)){
				char signals[1024];
				memset(signals, '\0', sizeof(signals));
				ret = recv(pipefd[0], signals, sizeof(signals), 0);
				if(ret < 0){
					//handle the error
					continue;
				} else if(ret == 0){
					continue;
				} else {
					for(int i = 0; i < ret; i++){
					switch (signals[i])
						case SIGALARM:
							/*关闭长时间不响应的连接*/
							timeout = true;//不立即处理定时任务
							break;
						case SIGTERM:
							stop_server = true;
					}
				}
			} else if(events[i].events & EPOLLIN){
				memset(users[sockfd].buf, '\0', BUFFER_SIZE);
				ret = recv(sockfd, users[sockfd].buf, BUFFER_SIZE - 1, 0);
				
				util_timer* timer = users[sockfd].timer;
				if(ret < 0){
					if(errno != EAGAIN){
						/*发生错误,则关闭连接,并移除定时器*/
						cb_func(&users[sockfd]);
						if(timer){
							timer_lst.del_timer(timer);
						}
					}
				} else if(ret == 0){
					/*对方已关闭连接,则关闭连接,并移除定时器*/
					cb_func(&users[sockfd]);
					if(timer){
						timer_lst.del_timer(timer);
					}
				} else {
					printf("get %d bytes of client data %s from %d\n", ret, users[sockfd].buf, sockfd);
					/*有数据,则需要调整定时器,以延迟该连接被关闭的时间*/
					if(timer){
						time_t cur = time(NULL);
						timer->expire = cur + 3*TIMESLOT;
						printf("adjust timer once\n");
						timer_lst.adjust_timer(timer);
					}
				}
			} else {
				//others
			}
		}
		/*最后处理定时事件*/
		if(timeout){
			timer_handler();
			timeout = false;
		}
	}
	close(listenfd);
	close(pipefd[0]);
	close(pipefd[1]);
	delete[] users;
	return 0;
}
Example #2
0
int main(int argc, char *argv[])
{
	bool stop_server = false;

	client_data *users;
	bool timeout = false;
	int epollfd;
	epoll_event events[MAX_EVENT_NUMBER];
	int listenfd;
	int ret = 0;
	struct sockaddr_in address;
	const char *ip;
	int port;

	if (argc < 2) {
		printf("usage: ./main ip_address port_number");
		return 1;
	}

	ip = argv[1];
	port = atoi(argv[2]);

	bzero(&address, sizeof(address));
	address.sin_family = AF_INET;
	inet_pton(AF_INET, ip, &address.sin_addr);
	address.sin_port = htons(port);

	listenfd = socket(PF_INET, SOCK_STREAM, 0);
	assert(listenfd >= 0);

	ret = bind(listenfd, (struct sockaddr *)&address, sizeof(address));
	assert(ret != -1);

	ret = listen(listenfd, 5);
	assert(ret != -1);

	epollfd = epoll_create(5);
	assert(epollfd != -1);
	addfd(epollfd, listenfd);

	ret = socketpair(PF_UNIX, SOCK_STREAM, 0, pipefd);
	assert(ret != -1);
	setnonblocking(pipefd[1]);
	addfd(epollfd, pipefd[0]);

	addsig(SIGALRM);
	addsig(SIGTERM);

	users = new client_data[FD_LIMIT];
	alarm(TIMESLOT);

	while (!stop_server) {
		int number = epoll_wait(epollfd, events, MAX_EVENT_NUMBER, -1);
		if ((number < 0) && (errno != EINTR)) {
			printf("epoll failure\n");
			break;
		}

		for (int i=0; i<number; ++i) {
			int sockfd = events[i].data.fd;
			if (sockfd == listenfd) {
				struct sockaddr_in client_address;
				socklen_t client_addlength = sizeof(client_address);
				int connfd = accept(listenfd, (struct sockaddr *)&client_address, &client_addlength);
				addfd(epollfd, connfd);
				users[connfd].address = client_address;
				users[connfd].sockfd = connfd;
				
				util_timer *timer = new util_timer;
				timer->user_data = &users[connfd];
				timer->cb_func = cb_func;
				time_t cur = time(NULL);
				timer->expire = cur + TIME_INACTIVE;
				users[connfd].timer = timer;
				timer_lst.add_timer(timer);
			} else if ((sockfd == pipefd[0]) && (events[i]).events & EPOLLIN) {
				char signals[1024];
				ret = recv(pipefd[0], signals, sizeof(signals), 0);
				if (ret == -1)
					continue;
				else if (ret == 0)
					continue;
				else {
					for (int i=0; i<ret; ++i) {
						switch (signals[i]) {
						case SIGALRM:
							timeout = true;
							break;
						case SIGTERM:
							stop_server = true;	
						}
					}
				}
			} else if (events[i].events & EPOLLIN) {
				util_timer *timer = users[sockfd].timer;
				memset(users[sockfd].buf, '\0', BUFFER_SIZE);
				ret = recv(sockfd, users[sockfd].buf, BUFFER_SIZE, 0);

				if (ret < 0) {
					if (errno != EAGAIN) {
						cb_func(&users[sockfd]);
						if (timer)
							timer_lst.del_timer(timer);
					}
				} else {
					users[sockfd].buf[ret-1] = '\0';
					printf("get %d bytes of client data %s from %d\n",
							ret, users[sockfd].buf, sockfd);
					if (timer) {
						time_t cur = time(NULL);
						timer->expire = cur + TIME_INACTIVE;
						timer_lst.adjust_timer(timer);
					}
				}
			}
		}

		if (timeout) {
			timer_handler();
			timeout = false;
		}
	}

	close(listenfd);
	close(pipefd[0]);
	close(pipefd[1]);
	delete []users;
	return 0;
}
void timer_handler(){
	/*定时处理任务:删除到期定时器并执行回调函数*/
	timer_lst.tick();
	/*因为一次alarm调用只会引起一次SIGALARM信号,所以要重新定时,以不断触发SIGALARM信号*/
	alarm(TIMESLOT);
}
Example #4
0
void timer_handler()
{
	timer_lst.tick();
	alarm(TIMESLOT);
}