IO多路复用-select模型

客户端代码见:C/S通信---服务器阻塞型使用

服务器端代码:

#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));
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);
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值