首页下载资源网络技术epoll实现简单聊天程序

ZIPepoll实现简单聊天程序

qq_3707730921.34KB需要积分:1

资源文件列表:

epoll.zip 大约有7个文件
  1. u_e_cli 17.41KB
  2. u_epoll_cli.c 2.78KB
  3. u_epoll_ser.c 4.39KB
  4. u_epoll_ser.cpp 4.66KB
  5. u_e_ser 17.52KB
  6. cpp 26.59KB
  7. Makefile 175B

资源介绍:

epoll实现简单聊天程序, 终端输入接收cli端数据,c 和c++ 实现ser c实现cli,c++方式支持多个客户端
#include #include #include #include #include #include #include #include #define SOCKET_PATH "/tmp/chat.sock" #define BUFFER_SIZE 1024 int main() { int server_socket, client_socket; struct sockaddr_un server_addr, client_addr; socklen_t client_len; int cli_fd = 0; // 创建 Unix 域套接字 server_socket = socket(AF_UNIX, SOCK_STREAM, 0); if (server_socket == -1) { perror("socket"); exit(EXIT_FAILURE); } // 清除旧的 socket 文件 unlink(SOCKET_PATH); // 准备地址结构 memset(&server_addr, 0, sizeof(server_addr)); server_addr.sun_family = AF_UNIX; strncpy(server_addr.sun_path, SOCKET_PATH, sizeof(server_addr.sun_path) - 1); // 绑定套接字 if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) { perror("bind"); exit(EXIT_FAILURE); } // 开始监听 if (listen(server_socket, 1) == -1) { perror("listen"); exit(EXIT_FAILURE); } // 接受客户端连接 /*client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_len); if (client_socket == -1) { perror("accept"); exit(EXIT_FAILURE); } // 设置套接字为非阻塞模式 int flags = fcntl(client_socket, F_GETFL, 0); fcntl(client_socket, F_SETFL, flags | O_NONBLOCK); */ char buffer[BUFFER_SIZE]; struct epoll_event events[3]; int epoll_fd = epoll_create1(0); if (epoll_fd == -1) { perror("epoll_create1"); exit(EXIT_FAILURE); } // 添加标准输入和客户端套接字到 epoll struct epoll_event event; event.events = EPOLLIN; event.data.fd = STDIN_FILENO; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, STDIN_FILENO, &event) == -1) { perror("epoll_ctl (stdin)"); exit(EXIT_FAILURE); } event.events = EPOLLIN | EPOLLET; // 边缘触发模式 event.data.fd = server_socket; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_socket, &event) == -1) { perror("epoll_ctl (client_socket)"); exit(EXIT_FAILURE); } while (1) { int nready = epoll_wait(epoll_fd, events, 3, -1); if (nready == -1) { perror("epoll_wait"); break; } for (int i = 0; i < nready; ++i) { if (events[i].data.fd == STDIN_FILENO) { if (fgets(buffer, BUFFER_SIZE, stdin) != NULL) { if(cli_fd != 0) write(cli_fd, buffer, strlen(buffer)); // 发送消息给客户端 } }else if (events[i].data.fd == server_socket) { printf("events[i].data.fd == server_socket accept\n"); client_len = sizeof(client_addr); client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_len); if (client_socket == -1) { perror("accept"); continue; } event.events = EPOLLIN | EPOLLET; // 边缘触发模式 event.data.fd = client_socket; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_socket, &event) == -1) { perror("epoll_ctl (client_socket)"); continue; } cli_fd = client_socket; }else/* if (events[i].data.fd == client_socket) */{ //printf("enter read, events[j].data.fd = 0x%x\n", events[i].data.fd); ssize_t nread = read(events[i].data.fd, buffer, BUFFER_SIZE - 1); if (nread > 0) { buffer[nread] = '\0'; printf("Received: %s", buffer); } else if (nread == 0) { printf("Client disconnected.\n"); epoll_ctl(epoll_fd, EPOLL_CTL_DEL, events[i].data.fd, NULL); close(events[i].data.fd); cli_fd = 0; continue; } else { perror("Error reading from client"); break; } } } } // 清理 close(client_socket); close(server_socket); close(epoll_fd); unlink(SOCKET_PATH); return 0; }
100+评论
captcha