select服务器

select 服务器,使用bitmap存储文件描述符进行监听IO,当监听的对象发生变化,进行置为1。使用vector和bitmap进行维护监听的IO,响应的IO分为socket listen 和 message ,前者进行accept创建通话的socket,后者进行通话(接收-recv).代码如下:

server.h

#pragma once
#include<iostream>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>


using namespace std;

namespace ser{
	class server{
		public:
		static int Socket(){
			 int sd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
			if(sd<0)
					exit(1);
			else
					return sd;
		}

		static bool Bind(int sd,uint32_t port){
			struct sockaddr_in laddr;
			laddr.sin_family=AF_INET;
			laddr.sin_port=htons(port);
			laddr.sin_addr.s_addr=INADDR_ANY;
			if(bind(sd,(const sockaddr*)&laddr,(socklen_t)sizeof laddr)<0)
					exit(1);
			return true;
		}

		static bool Listen(int sd){
			if(listen(sd,6)<0)
					exit(1);
			return true;
		}
	};
}

select_.h

#pragma once
#include<vector>
#include<unistd.h>
#include<time.h>
#include"server.h"
#include<algorithm>
namespace select_server{
	class select_server{
		private:
			int listen_sd;//the sock_fd to connect and message
			int port;
		public:
			select_server(int _port):port(_port){}

			//init server
			void InitServer(){
				listen_sd=ser::server::Socket();
				ser::server::Bind(listen_sd,port);
				ser::server::Listen(listen_sd);
			}

			void Run(){
				std::vector<int> readfds_arry(1024,-1);
				readfds_arry[0]=listen_sd;
				fd_set fds_read;
				while(1){
					FD_ZERO(&fds_read);
					//put the fd int array to bitmap fds_read
					for(int i=0;i<1024;++i){
						if(readfds_arry[i]!=-1)
							FD_SET(readfds_arry[i],&fds_read);							
					}
					int max_fd=*max_element(readfds_arry.begin(),readfds_arry.end());
					switch(select(max_fd+1,&fds_read,NULL,NULL,NULL)){ // if the fd 
					//changed return > 0
							case 0:
								cout<<"select timeout"<<endl;	
							break;
							case -1:
								cout<<"select error"<<endl;
							break;
							default:
							//have read thing
							{
                                 Solution(readfds_arry,fds_read);//array bitmap
							}
							break;

					}
				}
			}

			void Solution(vector<int>&v,fd_set& fds){
				for(int i=0;i<v.size();i++){
					if(FD_ISSET(v[i],&fds)){
						if(v[i]==listen_sd){ //new link  is not old link
							//new link is coming
							struct sockaddr raddr;//remoate address 
							socklen_t len;
							int new_sd=accept(listen_sd,&raddr,&len);
							cout<<"This is Connect and Message sock_fd"<<new_sd<<endl;
							//put the new_link into array
							if(AddfdsArray(v,new_sd)){
								cout<<"Add new_sd is successed!"<<endl;
							}
							else
								cout<<"Add new_sd is failed!"<<endl;
						}
						else
						{
							//Other thing is ready
							char str[1024];
							int sz=recv(v[i],&str,sizeof str,MSG_DONTWAIT);
							switch(sz){
								case 0:
									v[i]=-1;
									cout<<"The raddr is closed......"<<endl;
									break;
								case -1:
									cout<<"Read failed.";
									break;
								default:
									str[sz]='\0';
									cout<<"Sussed :"<<str<<endl;
									send(v[i],"Hello",6,0);
									break;
							}
						}
					}
				}
			}

			bool AddfdsArray(vector<int>& v,int sd){
				for(int i=0;i<v.size();i++){
					if(v[i]==-1){
						v[i]=sd;
						return true;
					}
				}
				return false;
			}
	};
}

select._cpp

#include"select_server.h"
int main(int argc,char** argv){
    if(argc!=2){
        cout<<"Error:argument is little"<<endl;
        exit(1);
    }
    select_server::select_server* sl =new select_server::select_server(stoi(argv[1]));
    sl->InitServer();
    sl->Run();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值