Linux Socket select IO多路复用

#include <sys/socket.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>

#define BACKLOG 5
#define MAXLINE 1024

int clients[BACKLOG];

int main()
{
	int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
	if (listen_fd  == -1)
	{
		printf("socket error[%d]:%s\n", errno, strerror(errno));
		exit(errno);
	}
	struct sockaddr_in server_addr;
	memset(&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	server_addr.sin_port = htons(55555);
	if (bind(listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
	{
		printf("bind error[%d]:%s\n", errno, strerror(errno));
                exit(errno);
	}
	
	int yes = 1;
	if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)	
	{
		printf("setsockopt error[%d]:%s\n", errno, strerror(errno));
                exit(errno);
        }

	if (listen(listen_fd, BACKLOG) == -1)
	{
		printf("listen error[%d]:%s\n", errno, strerror(errno));
                exit(errno);
	}
	

	fd_set rset;
	int maxfd = listen_fd;
	int conn_count = 0;
	int i = 0;
	while(1)
	{
		FD_ZERO(&rset);
		FD_SET(listen_fd, &rset);
		for (i=0; i< conn_count; i++)
		{
			if (clients[i]!=0)
			{
				FD_SET(clients[i], &rset);
			}
		}

		struct timeval tv;
		tv.tv_sec = 30;
		tv.tv_usec = 0;

		int ret = select(maxfd+1, &rset, NULL, NULL, &tv);
		if (ret < 0)
		{	
			printf("select error[%d]:%s\n", errno, strerror(errno));
			break;
		}else if (ret == 0)
		{
			printf("select timeout\n");
			continue;
		}
		
		if (FD_ISSET(listen_fd, &rset))
		{
			struct sockaddr_in client_addr;
			int sin_len = sizeof(client_addr);
			int client_fd = accept(listen_fd, (struct sockaddr *)&client_addr, &sin_len);
			if (client_fd == -1)
			{
				printf("accept error[%d]:%s\n", errno, strerror(errno));
				continue;
			}

			if (client_fd > maxfd) maxfd = client_fd;
			if (conn_count < BACKLOG)
			{
				printf("accept new connection %d\n", client_fd);
				clients[conn_count++] = client_fd;
				FD_SET(client_fd, &rset);
			}else
			{
				printf("max connections, exit\n");
				send(client_fd, "bye\n", 5, 0);
				close(client_fd);
				break;
			}
		}

		for(i=0; i<conn_count; i++)
		{
			if(FD_ISSET(clients[i], &rset))
			{
				char buffer[MAXLINE]={0};
				int recv_len = recv(clients[i], buffer, MAXLINE, 0);
				if (recv_len < 0)
				{
					printf("client %d recv error[%d]:%s\n", clients[i], errno, strerror(errno));
					printf("close client");
					close(clients[i]);
					FD_CLR(clients[i], &rset);
					clients[i]=0;
					continue;
				}
				printf("client %d recv len:%d, msg:%s\n", clients[i], recv_len, buffer);
			}		
		}
	}

	for (i=0; i<BACKLOG; i++)
	{
		if (clients[i]!=0)
		{
			send(clients[i], "bye\n", 5, 0);
			printf("close client %d\n", clients[i]);
			close(clients[i]);
		}
	}
	return 0;
}

猜你喜欢

转载自linguanghuan.iteye.com/blog/2195257