Select并发回声服务器实现(二)

服务端:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <math.h>
#define PORT "12345"
#define BUFFER_SIZE 1024
#define TRUE 1
#define FALSE 0

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");
  }

  fd_set reads, copy_reads;


  int option = TRUE;
  int op_size = sizeof(option);
  setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &option, op_size);

  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");
  }

  FD_ZERO(&reads);
  FD_SET(server_sock, &reads);
  int fd_max = server_sock;

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

  while (1) {

    timeout.tv_sec = 5;
    timeout.tv_usec = 0;
    copy_reads = reads;
    int fd_number = select(fd_max + 1, &copy_reads, 0, 0, &timeout);
    if (fd_number == -1) {
      break;
    }
    if (fd_number == 0) {
      printf("time out\n");
      continue;
    }

    for (int i = 0; i < fd_max + 1; i++) {
      if (FD_ISSET(i, &copy_reads)) {
        if (i == server_sock) {
          client_sock = accept(server_sock, (struct sockaddr *)&client_address, &client_address_size);
          if (client_sock == -1) {
            continue;
          } else {
            printf("new connect\n");
            FD_SET(client_sock, &reads);
            if (fd_max < client_sock) {
              fd_max = client_sock;
            }
          }

        } else {
          char buffer[BUFFER_SIZE];
          ssize_t str_len = read(i, buffer, BUFFER_SIZE);
          if (str_len == 0) {
            FD_CLR(i, &reads);
            close(i);
            printf("close client %d\n", i);
          } else {
            write(i, buffer, str_len);
          }
        }
      }
    }
  }
  close(server_sock);
  return 0;
}

客户端:

可参考之前客户端实现:

https://blog.csdn.net/supermario19/article/details/122902614?spm=1001.2014.3001.5501

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值