2024/4/25作业

select的TCP服务器

#include <code.h>

#define PORT 1100                   
#define IP "192.168.124.32"       

int deal_keyboardEvent(fd_set readfds, struct sockaddr_in pSaveCin[]);
int deal_CliConnectEvent(int sfd, struct sockaddr_in* saveCin, fd_set* preadfds, int* pmaxfd);
int deal_CliTalkEvent(int i, struct sockaddr_in saveCin[], fd_set *preadfds, int *pmaxfd);


int main(int argc, const char *argv[])                                                                                        
{
    int sfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sfd < 0)
    {
        fprintf(stderr, "line:%d  ", __LINE__);
        perror("socket");
        return -1;
    }
    printf("创建流式套接字成功  sfd=%d  __%d__\n", sfd, __LINE__);


    int reuse = 1;
    if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
    {
        fprintf(stderr, "line:%d  ", __LINE__);
        perror("setsockopt");
        return -1;

    }


    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)) < 0)
    {
        fprintf(stderr, "line:%d  ", __LINE__);
        perror("bind");
        return -1;
    }
    printf("bind success __%d__\n", __LINE__);

    if(listen(sfd, 128) < 0)
    {
        fprintf(stderr, "line:%d  ", __LINE__);
        perror("listen");
        return -1;
    }
    printf("listen success __%d__\n", __LINE__);

    fd_set readfds, tempfds;
    FD_ZERO(&readfds);

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

    int maxfd = sfd;

    int s_res;
    char buf[128];
    ssize_t res ;
    int newfd = -1;
    struct sockaddr_in saveCin[1024-3];     

    while(1)
    {
        tempfds = readfds; 
        s_res = select(maxfd+1, &tempfds, NULL, NULL, NULL);
        if(s_res < 0)
        {
            fprintf(stderr, "line:%d  ", __LINE__);
            perror("select");
            return -1;
        }
        else if(0 == s_res)
        {
            printf("time out....\n");
            break;
        }
        printf("__%d__\n", __LINE__);
  
        for(int i=0; i<=maxfd; i++)
        {
            if(FD_ISSET(i, &tempfds) == 0)      
                continue;
            if(0 == i){
                printf("触发键盘输入事件\n");
                deal_keyboardEvent(readfds, saveCin);
            }
            else if(i == sfd){
                printf("触发客户端连接事件\n");
                deal_CliConnectEvent(sfd, saveCin, &readfds, &maxfd);
            }
            else
            {
                printf("触发客户端交互事件\n");
                deal_CliTalkEvent(i, saveCin, &readfds, &maxfd);
            }
        }
    }
    close(sfd);
    return 0;
}

int deal_CliTalkEvent(int i, struct sockaddr_in saveCin[], fd_set *preadfds, int *pmaxfd)
{
    char buf[128] = "";
    bzero(buf, sizeof(buf));
    ssize_t res = recv(i, buf, sizeof(buf), 0);
    if(res < 0)
    {
        fprintf(stderr, "line:%d  ", __LINE__);
        perror("recv");
        return -1;
    }
    else if(0 == res)
    {
        printf("[%s:%d] 客户端下线 newfd=%d __%d__\n", inet_ntoa(saveCin[i-3].sin_addr), ntohs(saveCin[i-3].sin_port), i, __LINE__);

        close(i);
        FD_CLR(i, preadfds);      
        while(FD_ISSET(*pmaxfd, preadfds)==0 && (*pmaxfd--)>0);
        return -1;
    }
    printf("[%s:%d] newfd=%d %s __%d__\n",inet_ntoa(saveCin[i-3].sin_addr), ntohs(saveCin[i-3].sin_port), i, buf, __LINE__);
    strcat(buf, "*_*");
    if(send(i, buf, sizeof(buf), 0) < 0)
    {
        fprintf(stderr, "line:%d  ", __LINE__);
        perror("send");
        return -1;
    }
    printf("send success __%d__\n", __LINE__);

    return 0;
}

int deal_CliConnectEvent(int sfd, struct sockaddr_in* saveCin, fd_set* preadfds, int* pmaxfd)
{
    struct sockaddr_in cin;    
    socklen_t addrlen = sizeof(cin);

    int newfd = accept(sfd, (struct sockaddr*)&cin, &addrlen);
    if(newfd < 0)
    {
        fprintf(stderr, "line:%d  ", __LINE__);
        perror("accept");
        return -1;
    }
    printf("[%s:%d] 客户端连接成功 newfd=%d __%d__\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd, __LINE__);
    saveCin[newfd-3] = cin;

    FD_SET(newfd, preadfds);                       
    *pmaxfd = newfd>*pmaxfd ? newfd:*pmaxfd;       

    return 0;
}

int deal_keyboardEvent(fd_set readfds, struct sockaddr_in pSaveCin[])
{
    int sndfd;
    char buf[128];
    int res=scanf("%d %s", &sndfd, buf);    
    while(getchar() != '\n');
    if(res != 2)                         
    {
        printf("请输入正确格式: fd string\n");
        return -1;
    }

    if(sndfd<0 || sndfd>1023 || FD_ISSET(sndfd, &readfds) == 0)     
    {
        printf("请输入正确的文件描述符\n");
        return -1;
    }

    if(send(sndfd, buf, sizeof(buf), 0) < 0)
    {
        perror("send");
        return -1;
    }
    printf("发送给[%s:%d] fd=%d客户端 成功 __%d__\n",inet_ntoa(pSaveCin[sndfd-3].sin_addr), ntohs(pSaveCin[sndfd-3].sin_port), sndfd, __LINE__);

    return 0;
}

poll的客户端

#include <code.h>

int main(int argc, const char *argv[]) 
{
    if(argc < 3)
    {
        printf("请在命令行传入服务器的port 和 ip\n");
        return -1;
    }

    int cfd = socket(AF_INET, SOCK_STREAM, 0);
    if(cfd < 0)
    {
        fprintf(stderr, "line:%d  ", __LINE__);
        perror("socket");
        return -1;
    }                                                                                                         
    printf("create socket success, cfd=%d __%d__\n", cfd, __LINE__);

    struct sockaddr_in sin;
    sin.sin_family      = AF_INET;                  
    sin.sin_port        = htons(atoi(argv[1]));     
    sin.sin_addr.s_addr = inet_addr(argv[2]);       

    if(connect(cfd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
    {
        fprintf(stderr, "line:%d  ", __LINE__);
        perror("connect");
        return -1;
    }
    printf("connect server[%s:%s] success __%d__\n", argv[2], argv[1], __LINE__);

    struct pollfd fds[2];
    fds[0].fd = 0;            
    fds[0].events = POLLIN;    

    fds[1].fd = cfd;
    fds[1].events = POLLIN;

    char buf[128] = "";
    ssize_t res;

    int p_res;
    while(1)
    {
        p_res = poll(fds, 2, -1);
        if(p_res < 0)
        {
            fprintf(stderr, "line:%d  ", __LINE__);
            perror("poll");
            return -1;
        }
        else if(0 == p_res)
        {
            printf("time out....\n");
            break;
        }

        if((fds[0].revents & POLLIN) != 0)
        {
            fgets(buf, sizeof(buf), stdin);
            buf[strlen(buf)-1] = '\0';


            if(send(cfd, buf, sizeof(buf), 0) < 0)
            {
                fprintf(stderr, "line:%d  ", __LINE__);
                perror("send");
                return -1;
            }
            printf("send success __%d__\n", __LINE__);
        }


        if(fds[1].revents & POLLIN)
        {
 
            bzero(buf, sizeof(buf));
            res = recv(cfd, buf, sizeof(buf), 0);
            if(res < 0)
            {
                fprintf(stderr, "line:%d  ", __LINE__);
                perror("recv");
                return -1;
            }
            else if(0 == res)
            {
                printf("服务器下线 __%d__\n", __LINE__);
                break;
            }
            printf(":%s __%d__\n", buf, __LINE__);
        }
    }
    close(cfd);

    return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值