linux,socket编程,select,poll,epoll学习

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h> // 添加这一行
#include <string.h>    // 添加这一行
#include <pthread.h>
#include <poll.h>
#include <sys/epoll.h>

void *handle_client(void *arg)
{
    int clientfd = *(int *)arg;
    char buf[1024];
    printf("clientfd:%d\n", clientfd);
    while (1)
    {
        memset(buf, 0, sizeof(buf));
        int ret = recv(clientfd, buf, sizeof(buf), 0);
        if (ret <= 0)
        {
            printf("客户端断开连接\n");
            break;
        }
        printf("recv:%s\n", buf);
        char ans[] = "yesmefasrefas";
        int len = sizeof(ans);
        send(clientfd, ans, len, 0);
    }
    close(clientfd);
}
int main()
{
    // 创建socket_fd;
    printf("创建socket\n");
    int socketfd = socket(AF_INET, SOCK_STREAM, 0);
    if (socketfd < 0)
    {
        perror("socket");
        return -1;
    }

    // 绑定ip地址
    printf("绑定ip\n");
    struct sockaddr_in serveraddr;
    memset(&serveraddr, 0, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(9999);
    serveraddr.sin_addr.s_addr = inet_addr("0.0.0.0");
    if (bind(socketfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0)
    {
        perror("bind");
        return -1;
    }
    listen(socketfd, 10);
    printf("等待客户端连接\n");

    struct sockaddr_in clientaddr;
    int len = sizeof(clientaddr);
    printf("sockfd:%d\n", socketfd);

#if 0

    int clientfd = accept(socketfd, (struct sockaddr *)&clientaddr, &len);
    printf("客户端连接成功\n");
    char client_ip[INET_ADDRSTRLEN];
    inet_ntop(AF_INET, &(clientaddr.sin_addr), client_ip, INET_ADDRSTRLEN);
    printf("Client connected from IP: %s\n", client_ip);

#endif

#if 0
    //多线程
    while (1)
    {
        int clientfd = accept(socketfd, (struct sockaddr *)&clientaddr, &len);
        printf("客户端连接成功\n");
        pthread_t pid_t;
        pthread_create(&pid_t, NULL, handle_client, &clientfd);
    }
#endif
#if 0
    // select();
    fd_set rfds, rset;
    FD_ZERO(&rfds);          // 全部置0
    FD_SET(socketfd, &rfds); // sockfd 置1
    int maxfd = socketfd;
    while (1)
    {
        rset = rfds;
        int ready = select(maxfd + 1, &rset, NULL, NULL, NULL);
        if (FD_ISSET(socketfd, &rset)) // 判断是否在里面
        {
            int clientfd = accept(socketfd, (struct sockaddr *)&clientaddr, &len);

            printf("有情况!clientfd: %d\n", clientfd);
            FD_SET(clientfd, &rfds);
            maxfd = clientfd;
        }

        int i = 0;

        for (i = socketfd + 1; i <= maxfd; i++)
        {
            if (FD_ISSET(i, &rset))
            {
                printf("有数据到达了,fd:%d\n", i);
                char buf[1024];
                // printf("clientfd:%d\n", clientfd);
                memset(buf, 0, sizeof(buf));
                int ret = recv(i, buf, sizeof(buf), 0);
                if (ret <= 0)
                {
                    printf("客户端断开连接\n");
                    break;
                }
                printf("recv:%s\n", buf);
                char ans[] = "yesmefasrefas";
                int len = sizeof(ans);
                send(i, ans, len, 0);
                FD_CLR(i, &rfds);
                close(i);
            }
        }
    }

#endif

#if 0
    // poll();
    struct pollfd fds[1024];
    fds[socketfd].fd = socketfd;
    fds[socketfd].events = POLLIN;
    int maxfd = socketfd;
    while (1)
    {
        poll(fds, 1024, socketfd);
        if (fds[socketfd].revents & POLLIN)
        {
            int clientfd = accept(socketfd, (struct sockaddr *)&clientaddr, &len);
            printf("有情况!clientfd: %d\n", clientfd);
            fds[clientfd].fd = clientfd;
            fds[clientfd].events = POLLIN;
            maxfd = clientfd;
        }

        int i = 0;
        for (i = socketfd + 1; i <= maxfd; i++)
        {
            if (fds[i].revents & POLLIN)
            {
                printf("有数据到达了,fd:%d\n", i);
                char buf[1024];
                // printf("clientfd:%d\n", clientfd);
                memset(buf, 0, sizeof(buf));
                int ret = recv(i, buf, sizeof(buf), 0);
                if (ret <= 0)
                {
                    printf("客户端断开连接\n");
                    fds[i].fd = -1;
                    fds[i].events = 0;
                    close(i);
                }
                else
                {
                    printf("recv:%s\n", buf);
                    char ans[] = "yesmefasrefas";
                    int len = sizeof(ans);
                    send(i, ans, len, 0);
                }
            }
        }
    }

#endif

#if 1
    // epoll
    int epfd = epoll_create(1024);
    struct epoll_event ev;
    ev.events = EPOLLIN;
    ev.data.fd = socketfd;

    epoll_ctl(epfd, EPOLL_CTL_ADD, socketfd, &ev);
    struct epoll_event events[1024];
    while (1)
    {
        int ready = epoll_wait(epfd, events, 1024, -1);
        int i = 0;
        for (i = 0; i < ready; i++)
        {
            int connfd = events[i].data.fd;
            if (connfd == socketfd)
            {
                int clientfd = accept(socketfd, (struct sockaddr *)&clientaddr, &len);
                printf("有情况!clientfd: %d\n", clientfd);

                ev.data.fd = clientfd;
                ev.events = EPOLLIN;
                epoll_ctl(epfd, EPOLL_CTL_ADD, clientfd, &ev);
            }
            else if (events[i].events & EPOLLIN)
            {
                printf("有数据到达了,fd:%d\n", connfd);
                char buf[1024];
                // printf("clientfd:%d\n", clientfd);
                memset(buf, 0, sizeof(buf));
                int l = sizeof(buf);

                int ret = recv(connfd, buf, 5, 0);
                if (ret <= 0)
                {
                    printf("客户端断开连接\n");
                    epoll_ctl(epfd, EPOLL_CTL_DEL, connfd, NULL);
                    close(connfd);
                }
                else
                {
                    printf("recv:%s\n", buf);
                    char ans[] = "yesmefasrefas";
                    int len = sizeof(ans);
                    send(connfd, ans, len, 0);
                }
            }
        }
    }
#endif

    close(socketfd);
    return 0;
}

client代码

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h> // 添加这一行
#include <string.h>    // 添加这一行
#include <pthread.h>

int main(int argc, char *argv[])
{
    int sockfd;
    struct sockaddr_in servaddr;
    char buf[1024];
    int n;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);

    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(9999);
    servaddr.sin_addr.s_addr = inet_addr("113.45.173.146");
    connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
    char buffrecv[] = "123456789123456789123456789";
    send(sockfd, buffrecv, sizeof(buffrecv), 0);
    recv(sockfd, buf, 1024, 0);
    printf("recv:%s\n", buf);
    sleep(3);
    close(sockfd);
    return 0;
}
相关推荐
蜜獾云几秒前
docker 安装雷池WAF防火墙 守护Web服务器
linux·运维·服务器·网络·网络安全·docker·容器
小屁不止是运维2 分钟前
麒麟操作系统服务架构保姆级教程(五)NGINX中间件详解
linux·运维·服务器·nginx·中间件·架构
bitcsljl15 分钟前
Linux 命令行快捷键
linux·运维·服务器
ac.char18 分钟前
在 Ubuntu 下使用 Tauri 打包 EXE 应用
linux·运维·ubuntu
禁默31 分钟前
深入浅出:AWT的基本组件及其应用
java·开发语言·界面编程
Cachel wood37 分钟前
python round四舍五入和decimal库精确四舍五入
java·linux·前端·数据库·vue.js·python·前端框架
Code哈哈笑40 分钟前
【Java 学习】深度剖析Java多态:从向上转型到向下转型,解锁动态绑定的奥秘,让代码更优雅灵活
java·开发语言·学习
gb421528743 分钟前
springboot中Jackson库和jsonpath库的区别和联系。
java·spring boot·后端
程序猿进阶43 分钟前
深入解析 Spring WebFlux:原理与应用
java·开发语言·后端·spring·面试·架构·springboot
Youkiup1 小时前
【linux 常用命令】
linux·运维·服务器