当前位置: 首页 > article >正文

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



#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代码

 

 

#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;
}


http://www.kler.cn/news/363877.html

相关文章:

  • Java【多线程】单例模式
  • echarts散点图
  • VisionPro —— CogBlobTool斑点工具详解
  • Django学习- ORM基础操作_创建数据
  • 链表(虚拟头节点)
  • 机器学习-树结构2-随机森林
  • MATLAB基础应用精讲-【数模应用】负二项回归(附R语言和python代码实现)
  • OpenCV高级图形用户界面(16)设置一个已经创建的滚动条的最大值函数setTrackbarMax()的使用
  • 【跑酷项目02】实现触发并在前方克隆金币
  • 编辑器加载与AB包加载组合
  • SQL注入原理、类型、危害与防御
  • 使用cmdline-tools安装Android SDK与NDK
  • 驱动开发系列20 - Linux Graphics Xorg-server 介绍
  • 在 Python 中使用 Tensorflow 时出错:google.protobuf
  • 汽车票预订系统:SpringBoot技术应用
  • OpenIPC开源FPV之Ardupilot配置
  • 爬虫实战练习
  • 第T7周:咖啡豆识别
  • 多模态大语言模型(MLLM)-Blip3/xGen-MM
  • 姿态估计(一)——过程记录与问题记录
  • Spring Boot 3 声明式接口:能否完全替代 OpenFeign?
  • 写在RAGFlow开源2万星标之际
  • vue3使用element-plus手动更改url后is-active和菜单的focus颜色不同步问题
  • JavaFx -- chapter03(多线程网络通信)
  • Linux——K8S的pod的调度
  • 类的创建、构造器、实例属性、实例方法