服务器IO多路复用模型

简易多连接服务器
本文介绍了一个简易的多连接TCP服务器实现。服务器使用select机制监听多个客户端连接,并通过fork子进程来处理每个客户端请求。该服务器支持最多4096个并发连接。

一、服务器端代码:


#include<stdio.h>

#include<sys/socket.h>

#include<unistd.h>

#include<sys/types.h>

#include<errno.h>

#include<string.h>

#include<sys/stat.h>

#include<fcntl.h>

#include<netinet/in.h>

#include<stdlib.h>

#include<sys/select.h>

#include<sys/time.h>


int main()

{

int socket_fd,connect_fd;

struct sockaddr_in servaddr;

char buff[3];

int n;


//create socket

if((socket_fd = socket(AF_INET,SOCK_STREAM,0)) == -1)

{

printf("create socket error!\n");

exit(0);

}


//set local address

memset(&servaddr,0,sizeof(servaddr));    //memset可以方便的清空一个结构类型的变量或数组。


servaddr.sin_family = AF_INET;

servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

servaddr.sin_port = htons(8001);


//bind the local addr to socket

if(bind(socket_fd,(struct sockaddr*)&servaddr,sizeof(servaddr)) == -1)

{

printf("bind error %d!\n",errno);

exit(0);

}


//listen client

if(listen(socket_fd,5) == -1)

{

printf("listen error\n");

exit(0);

}

printf("服务器已经启动!\n");


fd_set fdset;

int accept_fd[4096]={0};


while(1)

{

FD_ZERO(&fdset);

FD_SET(socket_fd,&fdset);


for(int i=0;i<4096;i++)

{

if(accept_fd[i] != 0)

FD_SET(accept_fd[i],&fdset);

}


//fd_set fdread = fdset;

int ret = select(6,&fdset,0,0,0); //判断集合中是否有时间发生,没有时间发生的套接字将移出集合

if(ret > 0) //套接字有事件发生

{

for(int i=0;i<4096;i++)

{

if(accept_fd[i] == 0)

continue;

if( FD_ISSET(accept_fd[i],&fdset)) //如果是监听套接字说明有用户连接 

{

char buff[4096] = {0};

int len = recv(accept_fd[i],buff,4096,0);

if(len > 0)

{

printf("receive from client[%d]: %s\n",accept_fd[i],buff);

if(!fork())

{

if(send(accept_fd[i],"hello, you are connected\n",26,0) == -1)

perror("send error");

close(accept_fd[i]);

accept_fd[i] = 0;

}

}

else

{

accept_fd[i] = 0;

close(accept_fd[i]);

FD_CLR(accept_fd[i],&fdset);

}

}

}

if(FD_ISSET(socket_fd,&fdset))

{

struct sockaddr_in clientaddr;

unsigned int len = sizeof(clientaddr);

int newsocket = accept(socket_fd,(struct sockaddr *)&clientaddr,&len);

if(newsocket <=0)

{

printf("accept error!%s",strerror(errno));

continue;

}

int j =0 ;

for(;j<4096;j++)

{

if(accept_fd[j] == 0)

{

accept_fd[j] = newsocket;

break;

}

if(j == 4096)

{

printf("max connection,exit\n");

send(newsocket,"max connection exit",20,0);

close(newsocket);

break;

}

}

}

else if(ret == 0)

{

printf("timeout\n");

}

else

{

printf("select error\n");

break;

}

}

close(socket_fd);

}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值