io多路复用

select--->服务器

#include <myhead.h>
#define port 6666
#define ip "192.162.128.61"
int main(int argc, const char *argv[])
{
    //创建套接字
    int sfd = socket(AF_INET,SOCK_STREAM,0);
    //绑定
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port   = htons(port);
    sin.sin_addr.s_addr = inet_addr(ip);

    bind(sfd,(struct sockaddr*)&sin,sizeof(sin));
    printf("bind success\n");


    //监听
    listen(sfd,128);

    struct sockaddr_in cin;
    socklen_t addrlen = sizeof(cin);
    //创建一个集合
    fd_set = readfds,tempfds;
    FD_ZERO(&readfds);

    //将文件描述符添加到集合中
    FD_SET(0,&readfds);
    FD_SET(sfd,&readfds);

    ssize_t s_res = 0;                                                                                                                                                                                                                   
    int maxfd = sfd;
    char buf[128] ="";
    int newfd = -1;
    ssize_t res = 0;
    while(1)
    {
        tempfds = readfds;
        //调用select
        s_res = select(maxfd+1,&tempfds,NULL,NULL,NULL);
        if(s_res < 0)
        {
            ERR_MSG("select");
            return -1;

        }else if(s_res == 0)
        {
            printf("time out\n");
            return -1;

        }

        //运行到此时有文件描述符准备就绪
        for(int i = 0;i<=maxfd;i++)
        {
            if(FD_ISSET(i,&tempfds) == 0)//文件描述符不在结合中
                continue;
        //有文件描述符在结合中
        if(0 == i)
        {
            printf("fgets\n");
            fgets(buf,sizeof(buf),stdin);
            printf("%s\n",buf);

        }else if(i == sfd)
        {
            printf("accept\n");
            newfd = accept(sfd,(struct sockaddr*)&cin,&addrlen);
            printf("[%s:%d] newfd = %d 客户链接成功 __%d__\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd,__LINE__);

            //将newfd添加到集合中
            FD_SET(newfd,&readfds);
            //跟新maxfd
            maxfd = maxfd>newfd ? maxfd:newfd;




        }else
        {
            printf("recv and send\n");
            bzero(buf,sizeof(buf));
            res = recv(i,buf,sizeof(buf),0);
            if(res < 0)
            {
                ERR_MSG("recv");
                return -1;

            }
            else if(res == 0)  //有客户端退出
            {
                printf("[%s:%d]newfd = %d客户端下线\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),i);
                close(i);//关闭文件描述符
                FD_CLR(i,readfds);//删除下线的文件描述符
                //循环冲最大的文件描述符开始遍历,如果manxfd在集合中,maxfd就是最大值
                for(;maxfd>0;maxfd--)
                {
                    if(FD_ISSET(maxfd,readfds))
                    {
                        continue;

                    }

                }
                printf("[%s:%d] newfd = %d: %s\n",inet_ntoa(cin.sin_addr),htonsr(cin.sin_port),buf);



            }

            strcat(buf,"^_^");
            send(i,buf,sizeof(buf),0);
            printf("send success\n");

        }

        }



    }
    close(sfd);
    return 0;
}
                                                                                                                                                                                                                                         
                                                                                                                                                                                                                                         
                                                                                                                                                                                                                                         

select--->客户端

 #include <myhead.h>
 #define PORT 6666
 #define IP "192.168.124.61"
 int main(int argc, const char *argv[])
 {
     //创建套接字
     int cfd = socket(AF_INET,SOCK_STREAM,0);
     if(cfd<0)
     {
         ERR_MSG("scoket");
         return -1;
 
     }
     //绑定客户端ip非必须。
     //填充服务器的地址信息,给connect函数
     struct sockaddr_in sin;
     sin.sin_family    =  AF_INET;
     sin.sin_port      =htons(PORT);//服务器端口
     sin.sin_addr.s_addr  =inet_addr(IP);
     //链接到指定服务器
     if(connect(cfd,(struct sockaddr*)&sin,sizeof(sin))<0)
     {
         ERR_MSG("connect");
         return -1;
     }
     printf("connect success __%d__\n",__LINE__);
                                                                                                                                                                                                                                                      
 
     char buf[128] = "";
     ssize_t res = 0;
 
     //创建一个集合
     fd_set readfcs,tempfcs;
     FD_ZERO(&readfcs);//清空集合
 
     //将文件描述符添加到集合中
     FD_SET(0,&readfcs);
     FD_SET(cfd,&readfcs);
 
     ssize_t s_res = 0;
     while(1)
     {
         tempfcs = readfcs;
         //调用select
         s_res = select(cfd+1,&tempfcs,NULL,NULL,NULL);
         if(s_res <0 )
         {
             ERR_MSG("select");
             return -1;
 
         }else if(s_res == 0)
         {
             printf("time out\n");
             return -1;
 
         }
 
         for(int i =0;i<=cfd;i++)
         {
             if(FD_ISSET(i,&readfcs) == 0)
             {
                 continue;
 
             }
             if(0==i)
             {
                 bzero(buf,sizeof(buf));
                 printf("请输入:\n");
                 fgets(buf,sizeof(buf),stdin);
                 buf[strlen(buf)-1]='\0';
 
                 if(send(cfd,buf,sizeof(buf),0) <0 )
                 {
                     ERR_MSG("send");
                     return -1;
                 }
 
                 printf("send success __%d__\n",__LINE__);
 
             }
             else if(cfd == i)
             {
 
                 bzero(buf,sizeof(buf));
                 res = recv(cfd,buf,sizeof(buf),0);
                 if(res<0)
                 {
                     ERR_MSG("recv");
                     return -1;
 
                 }else if(0 == res)//有客户退出
                 {
                     close(i);
                     FD_CLR(i,&readfcs);
 
                     for(;cfd>0;cfd--)
                     {
                         if(FD_ISSET(cfd,&readfcs))
                         {
                             continue;
 
                         }
 
                     }
                     printf("[%s : %d ] 服务器下线__%d__\n",\
                             inet_ntoa(sin.sin_addr),ntohs(sin.sin_port),__LINE__);
                     break;
                 }
 
                 printf("[%s : %d ] %s__%d__\n",\
                         inet_ntoa(sin.sin_addr),ntohs(sin.sin_port),buf,__LINE__);
             }
 
 
         }
 
     }
     if(close(cfd)<0)
     {
         ERR_MSG("close");
         return -1;
 
     }
     return 0;
 
 
 }
 
 
                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                      

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值