写点什么

c++ 实现一个 tcp 高性能网络服务器

作者:linux大本营
  • 2023-04-26
    湖南
  • 本文字数:1963 字

    阅读完需:约 6 分钟

要编写一个 TCP 高性能网络服务器,需要使用多线程技术、异步 IO 和 epoll。

具体操作步骤如下:

  1. 创建 listenfd,使用 socket 函数生成一个 socket 描述符,并通过 bind 函数将其与特定 IP 地址和端口号绑定。

  2. 使用 listen 函数将 listenfd 设为监听状态,等待客户端连接。

  3. 使用 epoll 机制对 listenfd 进行监听,收到监听请求后,使用 accept 函数接受客户端的连接,并生成新的 socket 描述符 sockfd。

  4. 将新生成的 sockfd 插入 epoll 队列中,等待客户端发送请求。

  5. 当有请求到达时,使用异步 IO 进行读写操作,使用 recv/read 函数分别读取客户端发送的数据,并使用 send/write 函数将处理后的数据发送给客户端。

  6. 完成请求后,关闭 sockfd,等待下一个请求的到达。

  7. 当服务器关闭时,使用 close 函数关闭所有的 socket 描述符和 epoll 描述符。


下面是一个简单的 C++代码实现一个基于 epoll 的 tcp 高性能网络服务器:


#include <iostream>#include <cstring>#include <unistd.h>#include <arpa/inet.h>#include <sys/socket.h>#include <sys/epoll.h>
#define MAX_EVENTS 1024#define BUF_SIZE 4096
using namespace std;
int main(int argc, char* argv[]){ int listen_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (listen_fd == -1) { cerr << "Failed to create socket" << endl; return -1; }
struct sockaddr_in server_addr;memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_port = htons(12345);server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(listen_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) { cerr << "Failed to bind socket" << endl; return -1;}
if (listen(listen_fd, 5) == -1) { cerr << "Failed to listen" << endl; return -1;}
int epoll_fd = epoll_create(MAX_EVENTS);if (epoll_fd == -1) { cerr << "Failed to create epoll" << endl; return -1;}
struct epoll_event ev, events[MAX_EVENTS];ev.events = EPOLLIN; // 监听可读事件ev.data.fd = listen_fd;if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_fd, &ev) == -1) { cerr << "Failed to add listen socket to epoll" << endl; return -1;}
while (true) { int nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1); if (nfds == -1) { cerr << "Failed to wait for epoll events" << endl; break; }
for (int i = 0; i < nfds; ++i) { int fd = events[i].data.fd;
if (fd == listen_fd) { // 新连接 struct sockaddr_in client_addr; socklen_t len = sizeof(client_addr); int client_fd = accept(listen_fd, (sockaddr*)&client_addr, &len); if (client_fd == -1) { cerr << "Failed to accept client socket" << endl; continue; } cout << "New client connected: " << inet_ntoa(client_addr.sin_addr) << ":" << ntohs(client_addr.sin_port) << endl;
ev.events = EPOLLIN | EPOLLET; // 监听可读事件和边沿触发 ev.data.fd = client_fd; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &ev) == -1) { cerr << "Failed to add client socket to epoll" << endl; close(client_fd); } } else { // 有数据可读 char buf[BUF_SIZE]; int nread = read(fd, buf, BUF_SIZE); if (nread == -1) { cerr << "Failed to read data from socket" << endl; epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL); // 删除该socket close(fd); } else if (nread == 0) { cout << "Client disconnected" << endl; epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL); // 删除该socket close(fd); } else { cout << "Received data from client: " << buf << endl; write(fd, buf, nread); // 原样返回 } } }}
close(epoll_fd);close(listen_fd);
return 0;
复制代码


}这个服务器使用了 epoll 实现高效的事件驱动,支持边沿触发模式,处理新连接和数据读写。具体实现细节可以查看代码注释。


相关技术视频教程:c/c++ linux服务器开发/后台架构师免费学习地址

c/c++后端技术交流群:579733396

用户头像

还未添加个人签名 2020-11-26 加入

C/C++linux服务器开发群 812855908

评论

发布
暂无评论
c++实现一个tcp高性能网络服务器_TCP_linux大本营_InfoQ写作社区