epoll并发回声服务器实现(三)

本文介绍了如何使用Epoll事件驱动模型创建一个高性能的TCP服务器,包括socket操作、bind、listen、epoll_wait和accept等关键步骤,并展示了如何处理连接请求和数据交换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

服务端:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <arpa/inet.h>
#define PORT "12345"
#define BUFFER_SIZE 1024

void error_handler(const char *message) {
  fputs(message, stderr);
  fputc('\n', stderr);
  exit(1);
}

int main() {
  int server_sock;

  server_sock = socket(PF_INET, SOCK_STREAM, 0);
  if (server_sock == -1) {
    error_handler("socket() error");
  }

  struct epoll_event *ep_event;
  struct epoll_event event;

  struct sockaddr_in server_address;
  bzero(&server_address, sizeof(server_address));
  server_address.sin_family = AF_INET;
  server_address.sin_addr.s_addr = htonl(INADDR_ANY);
  server_address.sin_port = htons(atoi(PORT));

  if (bind(server_sock, (struct sockaddr *)&server_address, sizeof(server_address)) == -1) {
    error_handler("bind() error");
  }

  if (listen(server_sock, 5) == -1) {
    error_handler("listen() error");
  }

  int ep_fd = epoll_create(BUFFER_SIZE);
  ep_event = malloc(BUFFER_SIZE * sizeof(struct epoll_event));

  event.events = EPOLLIN;
  event.data.fd = server_sock;
  epoll_ctl(ep_fd, EPOLL_CTL_ADD, server_sock, &event);

  int event_cnt;

  int client_sock;
  struct sockaddr_in client_address;
  socklen_t client_address_size = sizeof(client_address);

  while (1) {
    event_cnt = epoll_wait(ep_fd, ep_event, BUFFER_SIZE, -1);
    if (event_cnt == -1) {
      printf("epoll_wait() error");
      break;
    }

    for (int i = 0; i < event_cnt; i++) {
      if (ep_event[i].data.fd == server_sock) {
        client_sock = accept(server_sock, (struct sockaddr *)&client_address, &client_address_size);
        if (client_sock == -1) {
          fputs("accept() error\n", stdout);
          continue;
        } else {
          fputs("new connect..\n", stdout);
        }

        event.events = EPOLLIN;
        event.data.fd = client_sock;
        epoll_ctl(ep_fd, EPOLL_CTL_ADD, client_sock, &event);
        printf("connect id : %d\n", client_sock);
      } else {
        char buffer[BUFFER_SIZE];
        ssize_t str_len = read(ep_event[i].data.fd, buffer, BUFFER_SIZE);
        if (str_len == 0) {
          epoll_ctl(ep_fd, EPOLL_CTL_DEL, ep_event[i].data.fd, NULL);
          close(ep_event[i].data.fd);
          printf("disconnect id : %d\n", ep_event[i].data.fd);
        } else {
          write(ep_event[i].data.fd, buffer, str_len);
        }
      }
    }
  }
  close(server_sock);
  close(ep_fd);
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值