【无标题】C/S通信基于select的步骤:

C/S通信之基于select的步骤:
{
	int listenfd, connfd, sockfd;	//
    struct sockaddr_in serv_addr, clie_addr;//存储客户端、服务器的IP和端口
    socklen_t clie_addr_len;	//用于accept,用于存储客户端的IP和端口
    int ret, maxfd, maxi, i, j, nready, nByte;
    fd_set rset, allset; 	//就绪集合、监听集合[监听与就绪分离]

    //1.创建本地套接字
    listenfd = socket(AF_INET,SOCK_STREAM,0);

    //2.地址复用和端口复用[避免服务器退出重连需要等待2tsl时间]
    int opt1 = 1;
    setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
    int opt = 1;
    setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));

    //3.服务器绑定IP和端口
    bzero(&serv_addr,sizeof(serv_addr)); 	//清零
	serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(atoi(SERV_PORT)); 	//SERV_PORT:服务器指定的端口
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);  //主机字节序转网络字节序
    
    bind(listenfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
    
    //4.服务器监听:将listenfd指向的文件对象的RCV/SND缓冲区摧毁,构建半连接和全连接队列,监听listenfd就是监听全连接队列是否有数据[就绪]
    listen(sockfd,128);
    
    //-------------------------------------------------------------------
    while(1)
    {
        //监听集合与就绪集合分离,所以每次轮询还得将监听集合的数据拷贝到就序集合中
        rset = allset;
        //1.监听: nready表示就绪时间发生的次数
        nready = select(maxfd+1,&rset,NULL,NULL,NULL);
    	//2.遍历整个监听集合,判断判断其文件描述符是否存在于rset中
        if(FD_ISSET(listenfd,&rset))
        {
            //2-1表示有新的连接请求:accept返回对应的文件描述符
            connfd = accept(listenfd,(struct sockaddr*)&clie_addr,&clie_addr_len);
            //将其添加进监听集合
            FD_SET(connfd,&allset);
        }
        else
        {
            //表示就旧连接上有数据,表明可以进行数据的传输
           	for(i = 0; i < maxi; ++i)
            {
                if((sockfd = client[i] < 0))
                {
                    continue;
                }
                
                if(FD_ISSET(sockfd,&rset))
                { 	//2-2旧连接上有数据来了 
                    if((nByte == read(sockfd,buf,sizeof(buf))) == 0)
                    {
                        //表明服务端想要断开请求
                        close(sockfd);
                        FD_CLR(sockfd,&allset); //将文件描述符从监听集合中删除
                        client[i] = -1;
                        continue;
                    }
                    else if(nByte > 0)
                    {
                        //根据业务逻辑上数据星星处理
                        write(sockfd,buf,nByte);
                        write(STDOUT_FILENO,buf,nByte);
                    }
                }
            }
        }
    }
    close(listenfd);
    
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值