Linux网络编程:epoll


#include <asm-generic/socket.h>
#include <cctype>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <netinet/in.h>
#include <strings.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <unistd.h>

static const uint16_t kPort = 3366;
static const char *kIpStr = "192.168.3.20";

int main() {
    
    

  char buffer[BUFSIZ];

  int listenFd = socket(AF_INET, SOCK_STREAM, 0);
  if (listenFd < 0) {
    
    
    perror("create socket error.]n");
    exit(-1);
  }
  int resuse = 1;
  setsockopt(listenFd, SOL_SOCKET, SO_REUSEADDR, &resuse, sizeof(resuse));

  sockaddr_in s_addr;
  bzero(&s_addr, sizeof(s_addr));
  s_addr.sin_family = AF_INET;
  s_addr.sin_port = htons(kPort);
  inet_pton(AF_INET, kIpStr, &s_addr.sin_addr);

  int ret = bind(listenFd, (const struct sockaddr *)&s_addr, sizeof(s_addr));
  if (ret < 0) {
    
    
    perror("bind socket error.\n");
    exit(-1);
  }

  listen(listenFd, 125);

  
  // 创建epoll
  int epfd = epoll_create(10);
  if (epfd < 0) {
    
    
    perror("create epoll error.\n");
    exit(-1);
  }

  // 添加epoll监听文件描述符
  epoll_event event;
  event.events = EPOLLIN;
  event.data.fd = listenFd;
  ret = epoll_ctl(epfd, EPOLL_CTL_ADD, listenFd, &event);
  if (ret < 0) {
    
    
    perror("epoll_ctl error.\n");
    exit(-1);
  }

  epoll_event ep_arr[10];
  while (1) {
    
    
    // ep_arr:存放监听返回的文件描述符数组,传出参数
    // 10:数组的长度
    //-1:阻塞直到有事件发生
    int nready = epoll_wait(epfd, ep_arr, 10, -1);
    if (nready == -1) {
    
    
      perror("epoll_watit error.\n");
      exit(-1);
    }

    for (int i = 0; i < nready; ++i) {
    
    
      if (!(ep_arr[i].events & EPOLLIN)) {
    
    
        continue;
      }
      if (ep_arr[i].data.fd == listenFd) {
    
    
        sockaddr_in c_addr;
        bzero(&c_addr, sizeof(c_addr));
        socklen_t c_addr_len = sizeof(c_addr);
        int connfd = accept(listenFd, (struct sockaddr *)&c_addr, &c_addr_len);
        if (connfd < 0) {
    
    
          perror("accept error.\n");
          continue;
        }

        struct epoll_event ev;
        ev.events = EPOLLIN;
        ev.data.fd = connfd;
        epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev);

      } else {
    
    
        int connfd = ep_arr[i].data.fd;
        memset(buffer, 0, sizeof(buffer));
        int num_read = read(connfd, buffer, sizeof(buffer));
        if (num_read < 0) {
    
    
          perror("read error\n");
        } else if (num_read == 0) {
    
    
          // 连接关闭,从epoll中移除
          epoll_ctl(epfd, EPOLL_CTL_DEL, connfd, nullptr);
          close(connfd);
          printf("scoket close.\n");
        } else {
    
    
          printf("server receive:%s\n", buffer);
          for (int i = 0; i < num_read; ++i) {
    
    
            buffer[i] = toupper(buffer[i]);
          }
          write(connfd, buffer, num_read);
          printf("response success.\n");
        }
      }
    }
  }
  close(listenFd);
  close(epfd);
  return 0;
}

猜你喜欢

转载自blog.csdn.net/xiwenhec/article/details/129430387