TCP协议+IO多路复用 --- select,poll,epoll分析
select、poll、epoll
select,poll,epoll都是IO多路复用的机制。I/O多路复用就是通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。
1.select
select目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点。select的一 个缺点在于单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024,可以通过修改宏定义甚至重新编译内核的方式提升这一限制,但 是这样也会造成效率的降低。
2.poll
不同与select使用三个位图来表示三个fdset的方式,poll使用一个 pollfd的指针实现。pollfd结构包含了要监视的event和发生的event,不再使用select“参数-值”传递的方式。同时,pollfd并没有最大数量限制(但是数量过大后性能也是会下降)。 和select函数一样,poll返回后,需要轮询pollfd来获取就绪的描述符。
3.epoll
epoll是在2.6内核中提出的,是之前的select和poll的增强版本。相对于select和poll来说,epoll更加灵活,没有描述符限制。epoll使用一个文件描述符管理多个描述符,将用户关系的文件描述符的事件存放到内核的一个事件表中,这样在用户空间和内核空间的copy只需一次。
参考来源:
Linux中select poll和epoll的区别
IO多路复用之select总结
IO多路复用之poll总结
IO多路复用之epoll总结
 下面关于三种方法的C语言实例。
客户端代码采用多路复用的思路实现。
  
   - 
    
     
    
    
     
      //客户端代码,可分别实现三种多路复用的形式 select、poll、epoll ;
     
    
- 
    
     
    
    
     
      //通过宏来实现
     
    
- 
    
     
    
    
     
      #include <stdio.h>
     
    
- 
    
     
    
    
     
      #include <string.h>
     
    
- 
    
     
    
    
     
      #include <unistd.h>
     
    
- 
    
     
    
    
     
      #include <errno.h>
     
    
- 
    
     
    
    
     
      #include <stdlib.h>
     
    
- 
    
     
    
    
     
      #include <strings.h>
     
    
- 
    
     
    
    
     
      #include <sys/types.h> /* See NOTES */
     
    
- 
    
     
    
    
     
      #include <sys/socket.h>
     
    
- 
    
     
    
    
     
      #include <netinet/in.h>
     
    
- 
    
     
    
    
     
      #include <netinet/ip.h> /* superset of previous */
     
    
- 
    
     
    
    
     
      #include <poll.h>
     
    
- 
    
     
    
    
     
      #include <sys/epoll.h>
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      #define SERV_PORT 5001
     
    
- 
    
     
    
    
     
      #define SERV_IP_ADDR "127.0.0.1"
     
    
- 
    
     
    
    
     
      #define BACKLOG 5
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      #define QUIT_STR "quit"
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      #define SELECT 0
     
    
- 
    
     
    
    
     
      #define POLL 0
     
    
- 
    
     
    
    
     
      #define EPOLL 1
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      void handle_select(int fd);
     
    
- 
    
     
    
    
     
      void handle_poll(int fd);
     
    
- 
    
     
    
    
     
      void handle_epoll(int fd);
     
    
- 
    
     
    
    
     
      void add_event(int epollfd,int fd,int state);
     
    
- 
    
     
    
    
     
      void handle_events(int epollfd,struct epoll_event *events,int num,int sockfd,char *buf);
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      int main(int argc, const char *argv[])
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
     	int fd;
     
    
- 
    
     
    
    
     	struct sockaddr_in sin;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	bzero(&sin,sizeof(sin));
     
    
- 
    
     
    
    
     
      	sin.sin_family = AF_INET;
     
    
- 
    
     
    
    
     	inet_pton(AF_INET,SERV_IP_ADDR,&sin.sin_addr);
     
    
- 
    
     
    
    
     
      	sin.sin_port = htons(SERV_PORT);
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	if( -1 == (fd = socket(AF_INET,SOCK_STREAM,0)) )
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     		perror("socket failed");
     
    
- 
    
     
    
    
     		return -1;
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	if( -1 == connect(fd,(struct sockaddr*)&sin,sizeof(sin)) )
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     		perror("connect failed");
     
    
- 
    
     
    
    
     		return -1;
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      #if SELECT
     
    
- 
    
     
    
    
     	handle_select(fd);
     
    
- 
    
     
    
    
     
      #endif
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      #if POLL
     
    
- 
    
     
    
    
     	handle_poll(fd);
     
    
- 
    
     
    
    
     
      #endif
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      #if EPOLL
     
    
- 
    
     
    
    
     	handle_epoll(fd);
     
    
- 
    
     
    
    
     
      #endif
     
    
- 
    
     
    
    
     	close(fd);
     
    
- 
    
     
    
    
     	return 0;
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      void handle_select(int fd)
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
     	int real_read;
     
    
- 
    
     
    
    
     	char buf[64];
     
    
- 
    
     
    
    
     
      	fd_set fdset;
     
    
- 
    
     
    
    
     	int maxfd = -1;
     
    
- 
    
     
    
    
     	struct timeval tout;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	while(1)
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		FD_ZERO(&fdset);
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		FD_SET(0,&fdset);
     
    
- 
    
     
    
    
     		FD_SET(fd,&fdset);
     
    
- 
    
     
    
    
     
      		maxfd = fd;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      		tout.tv_sec = 5;
     
    
- 
    
     
    
    
     
      		tout.tv_usec = 0;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		select(maxfd+1,&fdset,NULL,NULL,&tout);
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		if( FD_ISSET(0,&fdset) )
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			bzero(buf,sizeof(buf));
     
    
- 
    
     
    
    
     			do{
     
    
- 
    
     
    
    
     
      				real_read = read(0,buf,sizeof(buf));
     
    
- 
    
     
    
    
     
      			}while( real_read<0 && EINTR == errno );
     
    
- 
    
     
    
    
     			if(real_read < 0)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				perror("read");
     
    
- 
    
     
    
    
     				continue;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
     			else if( 0 == real_read )
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				continue;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     			write(fd,buf,strlen(buf)-1);
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     			if( 0 == (strncasecmp(buf,QUIT_STR,strlen(QUIT_STR))) )
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				printf("client quit\n");
     
    
- 
    
     
    
    
     				break;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		if( FD_ISSET(fd,&fdset) )
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			bzero(buf,sizeof(buf));
     
    
- 
    
     
    
    
     			do{
     
    
- 
    
     
    
    
     
      				real_read = read(fd,buf,sizeof(buf));
     
    
- 
    
     
    
    
     
      			}while( real_read<0 && EINTR == errno );
     
    
- 
    
     
    
    
     			if(real_read < 0)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				perror("read");
     
    
- 
    
     
    
    
     				continue;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
     			else if( 0 == real_read )
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				break;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     			printf("Received: %s\n",buf);
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     			if( 0 == (strncasecmp(buf,QUIT_STR,strlen(QUIT_STR))) )
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				printf("client quit\n");
     
    
- 
    
     
    
    
     				break;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      void handle_poll(int fd)
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
     	char buf[64];
     
    
- 
    
     
    
    
     	int maxfdp;
     
    
- 
    
     
    
    
     	struct pollfd pfds[2];
     
    
- 
    
     
    
    
     	int real_read;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      	pfds[0].fd = fd;
     
    
- 
    
     
    
    
     
      	pfds[0].events = POLLIN;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      	pfds[1].fd = 0;
     
    
- 
    
     
    
    
     
      	pfds[1].events = POLLIN;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      	maxfdp = 2;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	while(1)
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     		poll(pfds,maxfdp,5);
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		if (pfds[0].revents & POLLIN)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			bzero(buf,sizeof(buf));
     
    
- 
    
     
    
    
     			do{
     
    
- 
    
     
    
    
     
      				real_read = read(fd,buf,sizeof(buf));
     
    
- 
    
     
    
    
     
      			}while( real_read<0 && EINTR == errno );
     
    
- 
    
     
    
    
     			if(real_read < 0)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				perror("read");
     
    
- 
    
     
    
    
     				continue;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
     			else if( 0 == real_read )
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				break;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     			printf("Received: %s\n",buf);
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     			if( 0 == (strncasecmp(buf,QUIT_STR,strlen(QUIT_STR))) )
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				printf("client quit\n");
     
    
- 
    
     
    
    
     				break;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
     		if (pfds[1].revents & POLLIN)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			bzero(buf,sizeof(buf));
     
    
- 
    
     
    
    
     			do{
     
    
- 
    
     
    
    
     
      				real_read = read(0,buf,sizeof(buf));
     
    
- 
    
     
    
    
     
      			}while( real_read<0 && EINTR == errno );
     
    
- 
    
     
    
    
     			if(real_read < 0)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				perror("read");
     
    
- 
    
     
    
    
     				continue;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
     			else if( 0 == real_read )
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				continue;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     			write(fd,buf,strlen(buf)-1);
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     			if( 0 == (strncasecmp(buf,QUIT_STR,strlen(QUIT_STR))) )
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				printf("client quit\n");
     
    
- 
    
     
    
    
     				break;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      void handle_epoll(int sockfd)
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
     	int epollfd;
     
    
- 
    
     
    
    
     	struct epoll_event events[100];
     
    
- 
    
     
    
    
     	char buf[64];
     
    
- 
    
     
    
    
     	int ret;
     
    
- 
    
     
    
    
     
      	epollfd = epoll_create(1000);
     
    
- 
    
     
    
    
     	add_event(epollfd,0,EPOLLIN);
     
    
- 
    
     
    
    
     	add_event(epollfd,sockfd,EPOLLIN);
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	while(1)
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     
      		ret = epoll_wait(epollfd,events,100,5);
     
    
- 
    
     
    
    
     		handle_events(epollfd,events,ret,sockfd,buf);
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
     	close(epollfd);
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      void add_event(int epollfd,int fd,int state)
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
     	struct epoll_event ev;
     
    
- 
    
     
    
    
     
      	ev.events = state;
     
    
- 
    
     
    
    
     
      	ev.data.fd = fd;
     
    
- 
    
     
    
    
     	epoll_ctl(epollfd,EPOLL_CTL_ADD,fd,&ev);
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      void
     
    
- 
    
     
    
    
     
      handle_events(int epollfd,struct epoll_event *events,int num,int sockfd,char *buf)
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
     	int fd;
     
    
- 
    
     
    
    
     	int i;
     
    
- 
    
     
    
    
     	int real_read;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	for (i = 0;i < num;i++)
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     
      		fd = events[i].data.fd;
     
    
- 
    
     
    
    
     		if (events[i].events & EPOLLIN)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			if( fd == sockfd )
     
    
- 
    
     
    
    
     
      			{//判断就绪fd为连接套接字sockfd
     
    
- 
    
     
    
    
     				bzero(buf,64);
     
    
- 
    
     
    
    
     				do{
     
    
- 
    
     
    
    
     
      					real_read = read(sockfd,buf,64);
     
    
- 
    
     
    
    
     
      				}while( real_read<0 && EINTR == errno );
     
    
- 
    
     
    
    
     				if(real_read < 0)
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     					perror("read");
     
    
- 
    
     
    
    
     					continue;
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
     				else if( 0 == real_read )
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     					break;
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     				printf("Received: %s\n",buf);
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     				if( 0 == (strncasecmp(buf,QUIT_STR,strlen(QUIT_STR))) )
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     					printf("client quit\n");
     
    
- 
    
     
    
    
     					break;
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
     			else if( 0 == fd )
     
    
- 
    
     
    
    
     
      			{//那么判断就绪fd 为标准输入
     
    
- 
    
     
    
    
     				bzero(buf,64);
     
    
- 
    
     
    
    
     				do{
     
    
- 
    
     
    
    
     
      					real_read = read(0,buf,64);
     
    
- 
    
     
    
    
     
      				}while( real_read<0 && EINTR == errno );
     
    
- 
    
     
    
    
     				if(real_read < 0)
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     					perror("read");
     
    
- 
    
     
    
    
     					continue;
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
     				else if( 0 == real_read )
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     					continue;
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     				write(sockfd,buf,strlen(buf)-1);
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     				if( 0 == (strncasecmp(buf,QUIT_STR,strlen(QUIT_STR))) )
     
    
- 
    
     
    
    
     
      				{
     
    
- 
    
     
    
    
     					printf("client quit\n");
     
    
- 
    
     
    
    
     					break;
     
    
- 
    
     
    
    
     
      				}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
     
      }
     
    
 
服务端使用多线程的思想
  
   - 
    
     
    
    
     
      //循环里处理主监听套接字listenfd,accept监听请求连接。然后将每一个accept连接成功 返回的连接套接
     
    
- 
    
     
    
    
     
      //字connf分配给一个线程处理。。。
     
    
- 
    
     
    
    
     
      #include <stdio.h>
     
    
- 
    
     
    
    
     
      #include <string.h>
     
    
- 
    
     
    
    
     
      #include <unistd.h>
     
    
- 
    
     
    
    
     
      #include <errno.h>
     
    
- 
    
     
    
    
     
      #include <stdlib.h>
     
    
- 
    
     
    
    
     
      #include <strings.h>
     
    
- 
    
     
    
    
     
      #include <sys/types.h> /* See NOTES */
     
    
- 
    
     
    
    
     
      #include <sys/socket.h>
     
    
- 
    
     
    
    
     
      #include <netinet/in.h>
     
    
- 
    
     
    
    
     
      #include <netinet/ip.h> /* superset of previous */
     
    
- 
    
     
    
    
     
      #include <poll.h>
     
    
- 
    
     
    
    
     
      #include <sys/epoll.h>
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      #define SERV_PORT 5001
     
    
- 
    
     
    
    
     
      #define SERV_IP_ADDR "127.0.0.1"
     
    
- 
    
     
    
    
     
      #define BACKLOG 5
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      #define QUIT_STR "quit"
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      void *cli_data_handle(void* arg);
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      int main(int argc, const char *argv[])
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
     	int listenfd,connfd;
     
    
- 
    
     
    
    
     	struct sockaddr_in servaddr,cliaddr;
     
    
- 
    
     
    
    
     	socklen_t peerlen;
     
    
- 
    
     
    
    
     	char buf[64];
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	pthread_t thread;
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	bzero(&servaddr,sizeof(servaddr));
     
    
- 
    
     
    
    
     
      	servaddr.sin_family = AF_INET;
     
    
- 
    
     
    
    
     	inet_pton(AF_INET,SERV_IP_ADDR,(void *)&servaddr.sin_addr);
     
    
- 
    
     
    
    
     
      	servaddr.sin_port = htons(SERV_PORT);
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	if( -1 == (listenfd = socket(AF_INET,SOCK_STREAM,0)) )
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     		perror("socket failed");
     
    
- 
    
     
    
    
     		return -1;
     
    
- 
    
     
    
    
     
      	}	
     
    
- 
    
     
    
    
     	printf("socket create success....\n");
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	int b_reuse = 1;
     
    
- 
    
     
    
    
     	setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, &b_reuse, sizeof (int));
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	if(-1 == bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) )
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     		perror("bind failed");
     
    
- 
    
     
    
    
     		return -1;
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
     	printf("bind success....\n");
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	if( -1 == listen(listenfd,10) )
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     		perror("listen failed");
     
    
- 
    
     
    
    
     		return -1;
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
     	printf("listen success....\n");
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	while(1)
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     		bzero(&cliaddr,sizeof(cliaddr));
     
    
- 
    
     
    
    
     
      		peerlen = sizeof(cliaddr);
     
    
- 
    
     
    
    
     		if( (connfd = accept(listenfd,(struct sockaddr *)&cliaddr,&peerlen)) < 0)
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			perror("accept");
     
    
- 
    
     
    
    
     			return -1;
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     		if( 0 != pthread_create(&thread,NULL,cli_data_handle,(void *)&connfd) )
     
    
- 
    
     
    
    
     
      		{
     
    
- 
    
     
    
    
     			perror("pthread_create");
     
    
- 
    
     
    
    
     			return -1;
     
    
- 
    
     
    
    
     
      		}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	close(listenfd);
     
    
- 
    
     
    
    
     	return 0;
     
    
- 
    
     
    
    
     
      }
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     
      void *cli_data_handle(void* arg)
     
    
- 
    
     
    
    
     
      {
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     	char buf[64];
     
    
- 
    
     
    
    
     	int connfd = *(int *)arg;
     
    
- 
    
     
    
    
     	int real_read =0;
     
    
- 
    
     
    
    
     	while(1)
     
    
- 
    
     
    
    
     
      	{
     
    
- 
    
     
    
    
     			bzero(buf,sizeof(buf));
     
    
- 
    
     
    
    
     			do{
     
    
- 
    
     
    
    
     
      				real_read = read(connfd,buf,sizeof(buf));
     
    
- 
    
     
    
    
     
      			}while( real_read<0 && EINTR == errno );
     
    
- 
    
     
    
    
     			if(real_read < 0)
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				perror("read");
     
    
- 
    
     
    
    
     				continue;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
     			else if( 0 == real_read )
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				break;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
     			
     
    
- 
    
     
    
    
     			printf("Received:%s\n",buf);
     
    
- 
    
     
    
    
     			
     
    
- 
    
     
    
    
     			write(connfd,buf,strlen(buf));
     
    
- 
    
     
    
    
      
     
    
- 
    
     
    
    
     			if( 0 == (strncasecmp(buf,QUIT_STR,strlen(QUIT_STR))) )
     
    
- 
    
     
    
    
     
      			{
     
    
- 
    
     
    
    
     				printf("client quit\n");
     
    
- 
    
     
    
    
     				break;
     
    
- 
    
     
    
    
     
      			}
     
    
- 
    
     
    
    
     
      	}
     
    
- 
    
     
    
    
     	close(connfd);
     
    
- 
    
     
    
    
     
      }
     
    
 
结果验证

文章来源: blog.csdn.net,作者:hinzer,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/feit2417/article/details/82528105
- 点赞
- 收藏
- 关注作者
 
            
 
           
评论(0)