select服务器模型

Posted 药剂学徒

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了select服务器模型相关的知识,希望对你有一定的参考价值。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>

#define MAXLINE 80
#define port 8888
#define FD_SETSIZE 1024

int main(int argc,char* argv[]){
	int sockfd = socket(AF_INET,SOCK_STREAM,0);

	struct sockaddr_in server;
	bzero(&server,sizeof(server));
	server.sin_family = AF_INET;
	server.sin_port = htons(port);
	server.sin_addr.s_addr = htonl(INADDR_ANY);

	int ret = bind(sockfd,(struct sockaddr*)&server,sizeof(server));

	ret = listen(sockfd,10);

	struct sockaddr_in client_addr;
	socklen_t client_len = sizeof(client_addr);

	int client[FD_SETSIZE];
	int maxfd = sockfd;
	int i ;
	int maxi = -1;
	int nready;
	for(i = 0;i<FD_SETSIZE;i++){
		client[i] = -1;//用-1初始化client[]
	}
	
	fd_set allset,rset;
	int connfd;
	char str[MAXLINE];
	int sock;
	FD_ZERO(&allset);
	FD_SET(sockfd,&allset);//构造select监控文件描述符集
	int n;
	char buf[MAXLINE];
	for(;;){
		rset = allset;
		nready = select(maxfd+1,&rset,NULL,NULL,NULL);
		if(FD_ISSET(sockfd,&rset)){
			//new client connection
			connfd = accept(sockfd,(struct sockaddr*)&client_addr,&client_len);
			printf("recieved form %s \t %d\n",inet_ntop(AF_INET,&client_addr.sin_addr,str,sizeof(str)),ntohs(client_addr.sin_port));
			
			for(i = 0;i<FD_SETSIZE;i++){
				if(client[i]<0){
					client[i] = connfd;//保存accet返回的文件描述符到cleint[]里面
					break;
				}
			}
			//printf("1111\n");
			if(i == FD_SETSIZE){
				fputs("too many clients\n",stderr);
				exit(1);
			}
			//printf("22\n");
			FD_SET(connfd,&allset);//添加一个新的文件描述符到监控信号集
			//FD_SET(connfd,&rset);

			if(connfd>maxfd){
				maxfd = connfd;//select第一个参数的需要
			}

 			if(i>maxi){
				maxi = i;//更新client的最大下标值
			}
			//printf("3333");
			if(--nready == 0){
				continue;//如果没有更多的就绪文件描述符继续回到上面的select阻塞监听,负责处理未处理玩的就绪文件描述符
			}
			//printf("444");
		}

		for(i = 0;i<maxi;i++){
			//检测哪个client有数据就绪
			if((sock = client[i])<0){
				continue;
			}

			if(FD_ISSET(sock,&rset)){

				if((n = read(sock,buf,MAXLINE)) == 0){
					//当client关闭链接的时候,服务器段也关闭对应的链接
					close(sock);
					FD_CLR(sock,&allset);//解除select监控次文件描述符
					client[i] = -1;
				}

				else{
					int j ;
					for(j = 0;j<n;j++){
						buf[j] = toupper(buf[j]);
					}
					write(STDOUT_FILENO,buf,n);
				}

				if(--nready == 0){
					break;
				}
			}
		}
	}
	close(sockfd);
	return 0;
}

  服务端

#include<stdio.h>
#include<sys/socket.h>
#include<string.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<stdlib.h>

#define port 8888
#define buflen 1024
int main(int argc,char* argv[]){
	int sockfd = socket(AF_INET,SOCK_STREAM,0);
	int len ;
	if(sockfd<0){
		printf("socket failed\n");
		exit(1);
	}
	char recvbuf[buflen];

	struct sockaddr_in serv_addr;
	bzero(&serv_addr,sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(port);
	inet_pton(AF_INET,"127.0.0.1",&serv_addr.sin_addr);

	int ret = connect(sockfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
	printf("start to connect...\n");
	while(fgets(recvbuf,sizeof(recvbuf),stdin)!=NULL){
		write(sockfd,recvbuf,strlen(recvbuf));
		len = read(sockfd,recvbuf,sizeof(recvbuf));
		write(STDOUT_FILENO,recvbuf,len);
	}
	return 0;
}

  客户端

以上是关于select服务器模型的主要内容,如果未能解决你的问题,请参考以下文章

c# socket select 模型代码(u3d)

使用片段时 Intellij 无法正确识别 Thymeleaf 模型变量

php 一个自定义的try..catch包装器代码片段,用于执行模型函数,使其成为一个单行函数调用

如何防止在背面片段导航上再次设置视图模型

Discuz代码片段

常见的代码片段