linux网络编程:poll

#include <cctype>
#include <cerrno>
#include <cstdio>
#include <cstdlib>
#include <netinet/in.h>
#include <strings.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <cstring>
#include <poll.h>
#include <unistd.h>

static const uint16_t kServerPort = 3366;
static const char *kIpStr = "192.168.3.20";
static const int kMaxOpen = 1024;
int main() {
    
    

  char buffer[BUFSIZ];
  bzero(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));

  struct sockaddr_in s_addr;
  bzero(&s_addr, sizeof(s_addr));
  s_addr.sin_family = AF_INET;
  s_addr.sin_port = htons(kServerPort);
  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("sockt bind error.\n");
    exit(-1);
  }
  listen(listenFd, 125);

  // 定义一个用于存放监听socket文件描述符的数组
  struct pollfd cFdSet[kMaxOpen];
  cFdSet[0].fd = listenFd;
  cFdSet[0].events = POLLIN; // 设置读监听事件
  for (int i = 1; i < kMaxOpen; ++i) {
    
    
    cFdSet[i].fd = -1;
  }
  int lastIndex = 0;

  while (1) {
    
    
    // 参数1:用于监听的pollfd数组
    // 参数2:这里需要注意的是由于cFdSet是一个数组,当有fd被移出时,并不会自动合并前移
    //       所以这里的值应该是cFdSet数组中最后一个元素的下标+1;
    // 参数3:负数表示一直阻塞,直到有事件发生;
    //       0表示:无论是否有事件发生,都立即返回;
    //       大于0:阻塞到指定的毫秒数返回
    int ready_num = poll(cFdSet, lastIndex + 1, -1);

    // 检测是否有监听文件描述符上发生事件
    if (cFdSet[0].revents & POLLIN) {
    
    
      struct sockaddr_in c_addr;
      bzero(&s_addr, sizeof(s_addr));
      socklen_t addrLen = sizeof(s_addr);
      int connFd = accept(listenFd, (struct sockaddr *)&s_addr, &addrLen);
      if (connFd < 0) {
    
    
        perror("accept client socket error.\n");
        exit(-1);
      }
      int i = 1;
      for (; i < kMaxOpen; ++i) {
    
    
        if (cFdSet[i].fd == -1) {
    
    
          cFdSet[i].fd = connFd;
          cFdSet[i].events = POLLIN;
          if (i > lastIndex) {
    
    
            lastIndex = i;
          }
          break;
        }
      }
      if (i == kMaxOpen) {
    
    
        printf("too many client connect.\n");
      }
      if (--ready_num == 0) {
    
    
        continue;
      }
    }

    for (int i = 1; i < lastIndex + 1; ++i) {
    
    
      if (cFdSet[i].revents & POLLIN) {
    
    
        int read_num = read(cFdSet[i].fd, buffer, sizeof(buffer));
        if (read_num < 0) {
    
    
          if (errno == ECONNRESET) {
    
    
            close(cFdSet[i].fd);
            cFdSet[i].fd = -1;
          } else {
    
    
            perror("socket read error.\n");
          }
        } else if (read_num == 0) {
    
    
          close(cFdSet[i].fd);
          cFdSet[i].fd = -1;
        } else {
    
    
          printf("server receive:%s\n", buffer);
          for (int i = 0; i < read_num; ++i) {
    
    
            buffer[i] = toupper(buffer[i]);
          }
          write(cFdSet[i].fd, buffer, read_num);
        }
      }
    }
  }
  close(listenFd);
  return 0;
}

Guess you like

Origin blog.csdn.net/xiwenhec/article/details/129402287