服务器select模型

    多路转接I/O服务器中的一种:select服务器,该模型的服务器是将文件描述符放入队列中保存并监听,以轮询的机制去监听这些文件描述符,当相对应的文件描述符有读请求、写情况或异常发生时,对应的位将发生变化。select模型需要对所有监听的套接字实行轮询监听处理,当需要监听的套接字过多时,就可能出现响应不及时等问题,从而降低了服务器性能。

下面是服务器的实现(服务器将客户端发送过来的数据全部转换为大写)

#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#include <sys/select.h>

int main(int argc, char const *argv[])
{
	//创建套接字
	int listen_fd=socket(AF_INET,SOCK_STREAM,0);
	if(-1==listen_fd)
	{
		perror("socket");
		return ;
	}
	//构造地址结构
	struct sockaddr_in seraddr;
	memset(&seraddr,0,sizeof(seraddr));
	seraddr.sin_family=AF_INET;
	seraddr.sin_port=htons(1234);
	seraddr.sin_addr.s_addr=inet_addr("192.168.1.30");
	//将地址结构和套接字绑定
	if(bind(listen_fd,(struct sockaddr*)&seraddr,sizeof(seraddr))==-1)
	{
		perror("bind");
		return ;
	}
	//设置连接队列数目
	if(listen(listen_fd,10)==-1)
	{
		perror("listen");
		return ;
	}
	int maxfd=listen_fd;
	fd_set readset;
	struct timeval ts;
	ts.tv_sec=1;
	int clifd[128];
	int i,index=0;
	for(i=0;i<128;i++)
	{
		clifd[i]=-1;
	}

	while(1)
	{
		FD_ZERO(&readset);//清除
		FD_SET(listen_fd,&readset);//将listen_fd放到监听队列
		for(i=0;i<index;i++)
		{
			FD_SET(clifd[i],&readset);
		}
		//监听
		int ret=select(maxfd+1,&readset,NULL,NULL,&ts);
		if(ret==-1)
		{
			perror("select");
			return ;
		}
		//有请求发生
		if(ret>0)
		{
			//新的连接
			if(FD_ISSET(listen_fd,&readset))
			{
				struct sockaddr_in cliaddr;
				memset(&cliaddr,0,sizeof(cliaddr));
				int cli_size=sizeof(cliaddr);
				int fd=accept(listen_fd,(struct sockaddr*)&cliaddr,&cli_size);
				if(-1==fd)
				{
					perror("accept");
					return ;
				}
				clifd[index]=fd;
				if(clifd[index]>maxfd)
				{
					maxfd=clifd[index];
				}
				index++;
				printf("index:%d\n",index);
			}
			for(i=0;i<index;i++)
			{   //数据处理
				if(FD_ISSET(clifd[i],&readset))
				{
					char buf[1024];
					int j=0;
					int len=read(clifd[i],buf,sizeof(buf)-1);
					buf[len]='\0';
					printf("%s\n",buf);
					while(buf[j]!='\0')
					{
						if(buf[j]>='a' && buf[j]<='z')
						{
							buf[j] -= 0x20;
						}
						j++;
					}
					write(clifd[i],buf,strlen(buf));
				}
			}
		}
	}

	return 0;

}


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