day5 网络编程作业

TCP SELECT 服务器


#include <myhead.h>
#define IP "192.168.174.130"
#define PORT 8080
int main(int argc, const char *argv[])
{
    //创建套接字文件描述符
    int sfd = socket(AF_INET,SOCK_STREAM,0);
    if(sfd == -1)
        PRI_ERR("socket err");

    //bind绑定服务器的IP和PORT
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(PORT);
    sin.sin_addr.s_addr = inet_addr(IP);
    if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1)
        PRI_ERR("bind err");

    //设置sfd为监听模式
    if(listen(sfd,648)==-1)
        PRI_ERR("listen err");

    //创建select中的监听文件描述符结构体
    fd_set readfds,tempfds;
    FD_ZERO(&readfds);
    FD_ZERO(&tempfds);
    FD_SET(0,&readfds);
    FD_SET(sfd,&readfds);

    int maxfds = sfd;
    int nfd = -1;
    char sendbuf[128] = "";
    char recvbuf[128] = "";
    struct sockaddr_in cin;
    socklen_t addlen = sizeof(cin);
    while(1)
    {
        //select监听事件发生
        tempfds = readfds;
        int ret = select(maxfds+1,&tempfds,NULL,NULL,NULL);
        if(ret==-1)
        {
            perror("select err");
            continue;
        }
        //循环判断i是否是文件描述符集合中的数
        for(int i=0; i<=maxfds; i++)
        {
            if(!FD_ISSET(i,&tempfds))
                continue;
            //走到这说明是集合中的文件描述符
            //输入事件
            if(i==0)
            {
                int sndfd = -1;
                bzero(sendbuf,sizeof(sendbuf));
                scanf("%d %s",&sndfd,sendbuf);
                while(getchar()!='\n');
                if(send(sndfd,sendbuf,sizeof(sendbuf),0)==-1)
                {
                    perror("send err");
                    continue;
                }
                printf("send success");
            }

            //有新的客户端连接
            else if(i == sfd)
            {
                nfd = accept(sfd,(struct sockaddr*)&cin,&addlen);
                if(nfd == -1)
                {
                    perror("accept err");
                    continue;
                }
                //将nfd加入集合
                FD_SET(nfd,&readfds);
                printf("%s:%d 客户端已上线\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));
                
                //如果新的nfd是最大的fd,就要更新maxfds
                maxfds = nfd>maxfds?nfd:maxfds;
            }

            //客户端接收输出消息
            else
            {
                bzero(recvbuf,sizeof(recvbuf));
                int ret = recv(i,recvbuf,sizeof(recvbuf),0);
                if(ret == 0)
                {
                    printf("%s:%d 客户端已下线\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));
                    close(i);
                    FD_CLR(i,&readfds);
                    //删除后也要更新maxfds
                    while(!FD_ISSET(maxfds,&readfds)&&maxfds-->0);
                }
                
                printf("接收到消息:%s\n",recvbuf);
            }
        }
        
    }
    close(sfd);
    return 0;
}


在这里插入图片描述
TCP SELECT 客户端

#include <myhead.h>
#define PORT 8888
#define IP "192.168.174.130"
int main(int argc, const char *argv[])
{
    //select创建套接字
    int cfd = socket(AF_INET,SOCK_STREAM,0);
    if(cfd == -1)
        PRI_ERR("socket err");

    //connect 连接服务器
    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)
        PRI_ERR("connect err");

    //创建文件描述符集合
    fd_set readfds,tempfds;
    FD_ZERO(&readfds);
    FD_ZERO(&tempfds);
    FD_SET(0,&readfds);
    FD_SET(cfd,&readfds);
    
    char sendbuf[128] = "";
    while(1)
    {
        //selet监听事件发生
        tempfds = readfds;
        int ret = select(cfd+1,&tempfds,NULL,NULL,NULL);
        if(ret == -1)
        {
            perror("select err");
            continue;
        }
        //输入事件
        if(FD_ISSET(0,&tempfds))
        {
            bzero(sendbuf,sizeof(sendbuf));
            scanf("%s",sendbuf);
            printf("输入是:%s\n",sendbuf);
            //发送数据
            if(send(cfd,sendbuf,sizeof(sendbuf),0)==-1)
            {
                perror("send err");
                break;
            }
            printf("发送成功\n");

        }
        //发送/接收数据事件
        if(FD_ISSET(cfd,&tempfds))
        {
            
            //接收数据
            bzero(sendbuf,sizeof(sendbuf));
            int ret = recv(cfd,sendbuf,sizeof(sendbuf),0);
            if(ret == -1)
            {
                perror("recv err");
                continue;
            }
            else if(ret == 0)
            {
                printf("服务器下线\n");
                break;
            }
            printf("接收到数据%s\n",sendbuf);

        }

    }
    close(cfd);
    return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值