网络编程-day5

IO复用select实现TCP服务端

c 复制代码
#define IP "192.168.125.196"
#define PORT 8888
int main(int argc, const char *argv[])
{
    int sfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sfd == -1){
        perror("socket");
        return -1;
    }

    int reuse = 1;
    if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1){
        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)) == -1){
        perror("bind");
        return -1;
    }

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

    fd_set readfds, tempfds;
    FD_ZERO(&readfds);
    FD_SET(sfd, &readfds);
    int maxfd = sfd;
    int newfd = -1;
    struct sockaddr_in cin_arr[1024] = {0};
    struct sockaddr_in cin;
    socklen_t cinlen = sizeof(cin);
    char rbuf[128] = {0};
    while(1){
        tempfds = readfds;
        int res = select(maxfd+1, &tempfds, NULL, NULL, NULL);
        if(res == -1){
            perror("select");
            return -1;
        }else if(res == 0){
            printf("timeout\n");
            return -1;
        }
        for(int i=0; i<=maxfd; i++){
            if(!FD_ISSET(i, &tempfds)){
                continue;
            }
            if(i == sfd){
                newfd = accept(sfd, (struct sockaddr *)&cin, &cinlen);
                if(newfd == -1){
                    perror("accept");
                    return -1;
                }
                printf("[%s:%d]:online\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port));
                cin_arr[newfd] = cin;
                FD_SET(newfd, &readfds);
                if(newfd > maxfd){
                    maxfd = newfd;
                }
            }else{
                bzero(rbuf, sizeof(rbuf));
                int res = recv(i, rbuf, sizeof(rbuf), 0);
                if(res == 0){                                                                                 
                    printf("offline\n");
                    close(i);
                    FD_CLR(i, &readfds);
                    for(int k=maxfd; k>=sfd; k--){
                        if(FD_ISSET(k, &readfds)){
                            maxfd = k;
                            break;
                        }
                    }
                    continue;
                }
                printf("[%s:%d]:%s\n", inet_ntoa(cin_arr[i].sin_addr), ntohs(cin_arr[i].sin_port), rbuf);
                for(int j=4; j<=maxfd; j++){
                    if(j != i){
                        send(j, rbuf, strlen(rbuf), 0);
                    }
                }
            }
        }
    }
    close(sfd);
    return 0;
}

IO复用poll实现TCP客户端

c 复制代码
#include <myhead.h>
#define S_IP "192.168.125.196"
#define S_PORT 8888
#define C_IP "192.168.125.196"
#define C_PORT 7777
int main(int argc, const char *argv[])
{
    int cfd = socket(AF_INET, SOCK_STREAM, 0);
    if(cfd == -1){
        perror("socket");
        return -1;
    }

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

    struct sockaddr_in cin;
    cin.sin_family = AF_INET;
    cin.sin_port = htons(C_PORT);
    cin.sin_addr.s_addr = inet_addr(C_IP);
    if(bind(cfd, (struct sockaddr *)&cin, sizeof(cin)) == -1){
        perror("bind");
        return -1;
    }

    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(S_PORT);
    sin.sin_addr.s_addr = inet_addr(S_IP);
    if(connect(cfd, (struct sockaddr *)&sin, sizeof(sin)) == -1){
        perror("connect");
        return -1;
    }
    printf("connect success\n");

    struct pollfd pfd[2];
    pfd[0].fd = 0;
    pfd[0].events = POLLIN;
    pfd[1].fd = cfd;
    pfd[1].events = POLLIN;

    char rbuf[128] = {0};
    char wbuf[128] = {0};
    while(1){
        int ret = poll(pfd, 2, -1);
        if(ret == -1){
            perror("poll");
            return -1;
        }else if(ret == 0){
            printf("timeout\n");
            return -1;
        }
        if(pfd[0].revents == POLLIN){
            bzero(wbuf, sizeof(wbuf));
            fgets(wbuf, sizeof(wbuf), stdin);
            int len = strlen(wbuf);
            if(wbuf[len-1] == '\n'){
                wbuf[len-1] = 0;
            }
            send(cfd, wbuf, len, 0);
        }
        if(pfd[1].revents == POLLIN){
            bzero(rbuf, sizeof(rbuf));
            int res = recv(cfd, rbuf, sizeof(rbuf), 0);
            if(res == 0){
                printf("offline\n");
                break;
            }
            printf("[%s:%d]:%s\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), rbuf);
        }
    }
    return 0;
}                                                                                                  
相关推荐
ShineWinsu29 分钟前
对于Qt:QDial常见属性以及信号的解析
开发语言·c++·qt·gui·客户端·旋钮·qdial
Java后端的Ai之路3 小时前
RAG 还是 Agent 自主检索?Claude Code 删掉向量库之后,我把选型讲透了
开发语言·人工智能·prompt·agent·rag
我是koten3 小时前
【运维杂谈】K8s遇到Terminating的名称空间删除不了怎么办?(解决方案亲测有效)
linux·运维·服务器·云原生·kubernetes·k8s·名称空间
starzy19903 小时前
深入理解Scala高阶函数:函数式编程核心
开发语言·scala
czq_26867194879 小时前
Python打卡第46天
开发语言·python
Zwawa10 小时前
用两个按键做一个OLED菜单:先把选择和执行分开
c语言·单片机·嵌入式
2601_9679873710 小时前
安装 Redis 或 Redis Stack
linux·windows·redis·macos·安装
feng_you_ying_li10 小时前
linux之数据链路层
linux·网络·智能路由器
Evand J11 小时前
【MATLAB例程介绍】(17)永磁同步电机(PMSM)基于自适应无迹卡尔曼滤波(AUKF)的电流噪声在线估计。测量噪声协方差自适应与转速估计对比仿真
开发语言·matlab·卡尔曼滤波·无迹卡尔曼滤波·pmsm·电机滤波
GeW12 小时前
高端化走到深处,是数据库和Linux的事
linux