如何实现一个百万并发量的TCP服务器

本文介绍了如何设计和实现一个能处理百万并发连接的TCP服务器,采用epoll和线程池技术,通过调整系统参数解决文件打开限制和端口耗尽问题,并针对客户端连接超时和服务器空间不足等问题提出解决方案。
摘要由CSDN通过智能技术生成

朋友问我:你现在年薪百万吗?我说:我没有,倒是并发量超百万的服务器可以有(坏笑)。

目标

实现一个并发量超一百万的TCP服务器

基本设计思路

使用epoll获取请求+线程池处理请求

环境介绍

四台虚拟机(一个服务端以及三个服务端)
服务端硬件配置要求:双核处理器,4G运行内存
客服端硬件配置要求:单核处理器,2G运行内存
虚拟机运行操作系统:ubuntu server 64位
虚拟机软件:VMware Fusion
操作系统:macOS

代码实现

服务器端

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <stdbool.h>

#include <errno.h>
#include <fcntl.h>
#include <sys/epoll.h>

#define COUNT_PORT 100 
#define EPOLL_SIZE 2048
//任务队列中的任务数目
// #define COUNT_TASK 1024
//线程池中线程数量
#define COUNT_WORK 4
//缓存长度
#define BUFFER_LENGTH 1024


//双向链表的插入
#define LIST_INSERT(item,list) do \
{
                                      \
    item->next = list->next;      \
    if(list->next != NULL)        \
        list->next->pre = item;   \
    list->next = item;            \
    item->pre = list;             \
} while (0);                      

//双向链表 删除节点
#define LIST_REMOVE(item,list) do       \
{
                                            \
    if(item != NULL){
                        \
        item->pre->next = item->next;   \
        if(item->next != NULL)          \
            item->next->pre = item->pre;\
    }                                   \
} while (0);                     

//任务队列
struct Task
{
   
    //socket_fd
    int socket_fd;
    //epoll_fd
    int epoll_fd;
    //监听套接字数组
    int *listen_socket;
    //前驱节点
    struct Task *pre;  
    //后继节点
    struct Task *next;
    //任务函数
    void (*function_task)(int socket_fd, int epoll_fd, int *listen_socket);
};

//工作队列
struct Work
{
   
    //进程ID
    pthread_t thread_id;
    //前驱节点
    struct Work *pre;
    //后继
    struct Work *next;
};

//线程池
struct  ThreadPool
{
   
    //工作队列
    struct Work *works;
    //任务队列
    struct Task *tasks;
    //互斥锁
    pthread_mutex_t mutex;
    //条件变量
    pthread_cond_t cond;
};

//推送任务
int task_push(struct Task *task,struct ThreadPool *thread_pool){
   
    //上锁
    int res = pthread_mutex_lock(&thread_pool->mutex);
    if (res)
    {
   
        perror("pthread_mutex_lock\n");
        return -1;
    }

    LIST_INSERT(task,thread_pool->tasks);
    pthread_cond_signal(&thread_pool->cond);

    //解锁
    res =</
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值