服务器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;

}
时间: 2024-08-04 09:02:46

服务器select模型的相关文章

网络服务器架构模型与比较

事件驱动为广大的程序员所熟悉,其最为人津津乐道的是在图形化界面编程中的应用:事实上,在网络编程中事件驱动也被广泛使用,并大规模部署在高连接数高吞吐量的服务器程序中,如 http 服务器程序.ftp 服务器程序等.相比于传统的网络编程方式,事件驱动能够极大的降低资源占用,增大服务接待能力,并提高网络传输效率. 关于本文提及的服务器模型,搜索网络可以查阅到很多的实现代码,所以,本文将不拘泥于源代码的陈列与分析,而侧重模型的介绍和比较.使用 libev 事件驱动库的服务器模型将给出实现代码. 本文涉及

Winsock IO模型之select模型

之所以称其为select模型是因为它主要是使用select函数来管理I/O的.这个模型的设计源于UNIX系统,目的是允许那些想要避免在套接字调用上阻塞的应用程序有能力管理多个套接字. int select( int nfds,                                                 // 忽略,仅是为了与Berkeley套接字兼容 fd_set* readfds,                                  // 指向一个套接字集合,

利用NIO的Selector处理服务器-客户端模型

内容:这是一个简单的服务器-客户端模型,利用了NIO的Selector来处理多个管道.至于Selector的介绍看这里 NIOServer: public class NIOServer { public static void main(String[] args) throws IOException, InterruptedException { Selector selector = Selector.open(); ServerSocketChannel serverSocketCha

socket select模型

由于socket recv()方法是堵塞式的,当多个客户端连接服务器时,其中一个socket的recv调用时,会产生堵塞,使其他连接不能继续. 如果想改变这种一直等下去的焦急状态,可以多线程来实现(不再等待,同时去recv,同时阻塞),每个socket连接使用一个线程,这样效率十分低下,根本不可能应对负荷较大的情况(是啊,占用各种资源,电脑啊,你耗不起). 这时候我们便可以采取select模型.select允许进程指示内核等待多个事件中的任何一个发生,并仅在有一个或多个事件发生或经历一段指定时间

几种经典的网络服务器架构模型的分析与比较

原文出处:http://blog.csdn.net/lmh12506/article/details/7753978 前言 事件驱动为广大的程序员所熟悉,其最为人津津乐道的是在图形化界面编程中的应用:事实上,在网络编程中事件驱动也被广泛使用,并大规模部署在高连接数高吞吐量的服务器程序中,如 http 服务器程序.ftp 服务器程序等.相比于传统的网络编程方式,事件驱动能够极大的降低资源占用,增大服务接待能力,并提高网络传输效率. 关于本文提及的服务器模型,搜索网络可以查阅到很多的实现代码,所以,

Select 模型1

Select模型原理 利用select函数,判断套接字上是否存在数据,或者能否向一个套接字写入数据.目的是防止应用程序在套接字处于锁定模式时,调用recv(或send)从没有数据的套接字上接收数据,被迫进入阻塞状态. select参数和返回值意义如下: int select ( IN int nfds,                           //0,无意义 IN OUT fd_set* readfds,      //检查可读性 IN OUT fd_set* writefds,  

socket select()模型

转载:http://www.cnblogs.com/xiangshancuizhu/archive/2012/10/05/2711882.html 由于socket recv()方法是阻塞式的,当有多个客户端连接服务器时,其中一个socket的recv调用产生了阻塞,使其他链接不能继续.如果想改变这种一直等下去的焦急状态,可以多线程来实现(不再等待,同时去recv,同时阻塞),每个socket连接使用一个线程,这样效率十分低下,根本不可能应对负荷较大的情况(是啊,占用各种资源,电脑啊,你耗不起)

基于Select模型的混乱聊天室v1.0

最近在无聊完成了一个简单的基于select模型的匿名聊天室程序,均使用C++开发 服务器工作原理: 每接收一条客户端的信息,就将遍历所有的socket,并将该信息发给所有的客户端. 客户端使用两条线程,一个是接收服务端信息的线程,一个是等待阻塞输入的线程,获得输入时,将输入发送到服务器. 项目源码:https://github.com/coderguang/Chat 版本为v2.0的release. 其中ComLib也在github上 服务器核心代码: int main(int argc,cha

Select模型

参考:http://m.blog.csdn.net/article/details?id=51420015 一.套接字模式 套接字模式简单的决定了操作套接字时,Winsock函数是如何运转的.Winsock以两种模式执行I/O操作:阻塞和非阻塞. 在阻塞模式下,执行I/0的Winsock调用(如send和recv)一直到操作完成才返回. 非阻塞模式下,Winsock函数会立刻返回 1.阻塞模式 套接字创建时,默认工作在阻塞模式下,列入对recv函数的调用会使程序进入等待状态,知道接收到数据才返回