网络day4(2023/12/21)

###select 实现客户端

#include
#define IP "192.168.125.100"
#define PORT 8888

int main(int argc, const char *argv[])
{
    int cfd=socket(AF_INET,SOCK_STREAM,0);
    if(cfd == -1)
    {
        perror("create socket");
        return -1;
    }

    struct sockaddr_in sin;
    sin.sin_family=AF_INET;
    sin.sin_addr.s_addr=inet_addr(IP);
    sin.sin_port=htons(PORT);

    if(connect(cfd,(struct sockaddr*)&sin,sizeof(sin)) ==-1)
    {
        perror("bind error");
        return -1;
    }

    fd_set readfds;

    FD_ZERO(&readfds);

    FD_SET(cfd,&readfds);
    FD_SET(0,&readfds);

    char buf[128];
    char rbuf[128];
    int res=0;
    int count;

    fd_set tempfds;
    while(1)
    {
        tempfds=readfds;

        res=select(cfd+1,&tempfds,NULL,NULL,NULL);
        if(res == -1)
        {
            perror("select error");
            return -1;
        }else if(res == 0)
        {
            printf("time out\n");
            return -1;
        }

        if(FD_ISSET(0,&tempfds))
        {
            memset(buf,0,sizeof(buf));
            fgets(buf,sizeof(buf),stdin);
            send(cfd,buf,sizeof(buf),0);
            printf("发送成功\n");
        }

        if(FD_ISSET(cfd,&tempfds))
        {
            memset(rbuf,0,sizeof(buf));
            count=recv(cfd,rbuf,sizeof(rbuf),0);
            if(count==0)
            {
                printf("服务器已经下线\n");
                break;
            }
            printf("收到信息:%s\n",rbuf);
        }

    }
    return 0;

}     

网络day4(2023/12/21)_第1张图片
###POLL实现客户端

#include
#define PORT 8888
#define IP "192.168.111.26"

struct fdIndex{
    int newfd;
    int index;
    struct sockaddr_in cin2;
};//存储newfd、索引与newfd对应的地址信息结构体

int main(int argc, const char *argv[])
{
    int sfd=socket(AF_INET,SOCK_STREAM,0);
    if(sfd==-1)
    {
        perror("create socket");
        return -1;
    }

    int reuse=1;
    if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1)
    {
        perror("reues");
        return -1;
    }

    struct sockaddr_in sin;
    sin.sin_family=AF_INET;
    sin.sin_addr.s_addr=inet_addr(IP);
    sin.sin_port=htons(PORT);

    if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1)
    {
        perror("bind error");
        return -1;
    }

    if(listen(sfd,128)==-1)
    {
        perror("listen");
        return -1;
    }

    struct sockaddr_in cin;
    socklen_t slen=sizeof(cin);
    int newfd=-1;

    struct pollfd fds[128];

    struct fdIndex info[128];//用来存储下标的结构体
    for(int i=0;i<128;i++)
    {
        info[i].newfd=-1;
        info[i].index=-1;
    }//初始化结构体

    fds[0].fd=0;
    fds[0].events = POLLIN;

    fds[1].fd=sfd;
    fds[1].events= POLLIN;
    
    int len=2;
    int index;
    int maxfd=0;

    char rbuf[128];

    int index2;

    int arrnum=2;
    int res;

    while(1)
    {
        res=poll(fds,arrnum,-1);
        if(res<0)
        {
            perror("poll error");
            return -1;
        }else if(res == 0)
        {
            perror("timeout\n");
            return -1;
        }
        
        for(int i=1;i<=len;i++)
        {
            if(fds[i].revents!=POLLIN)continue;
            if( i == 1)
            {
                if((newfd=accept(sfd,(struct sockaddr*)&cin,&slen))==-1)
                {
                    perror("accept error");
                    return -1;
                }
                    
                info[len].newfd=newfd;//记录下newfd
                info[len].index=len;//记录下此时newfd存储在fds数组中的下标
                info[len].cin2=cin;//赋值地址信息结构体

                fds[len].fd=newfd;
                fds[len].events=POLLIN;
                len++;//表长度加一
                arrnum++;
                printf("[%s:%d]链接成功,newfd=%d\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd); 
            }else{
                memset(rbuf,0,sizeof(rbuf));
                res=recv(fds[i].fd,rbuf,sizeof(rbuf),0);
                if(res == 0)
                {
                    printf("客户端下线\n");
                    close(fds[len].fd);
                    
                    for(int j=0;i<128;i++)
                    {
                        if(info[j].newfd==fds[i].fd)
                        {
                            index2=info[j].index;
                        }
                    }

                    for(int i=index2;i<len;i++)
                    {
                        fds[i]=fds[i+1];
                    }
                    len--;//表长度减少1
                    arrnum--;
                }

                for(int j=0;j<128;j++)
                {
                    if(info[j].newfd==fds[i].fd)
                    {
                        printf("[%s:%d]:%s\n",inet_ntoa(info[j].cin2.sin_addr),\
                        ntohs(info[j].cin2.sin_port),rbuf);
                        break;
                    }
                }
            }   
        }
    }
    return 0;
}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  
~                                

网络day4(2023/12/21)_第2张图片

你可能感兴趣的:(网络)