C1000K 实战,基于 Libev - 续

最近公司年终旅游,博客也是有很久没有更新了,这次继续我们上一次的高并发服务器编程。 上一篇文章讲解了要在Linux系统上实现C1000K服务器所需要进行的系统调优操作,那么我们现在就开始来编写我们的程序吧~

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <arpa/inet.h>
#include <ev.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <err.h>
#include <unistd.h>

typedef struct
{
    int fd; // 客户端套接字
    ev_io ev_read; // 读取事件监听器
}client_t;

static int server_port = 10204;
struct ev_loop *loop;

ev_io ev_accept; // 监听器

static int userNum;
static void incr_online_user()
{
    ++userNum;
    printf("Current Online User Num:%d\n",userNum);
}

static void des_online_user()
{
    --userNum;
    printf("Current Online User Num:%d\n",userNum);
}

// 设置非阻塞套接字
static int set_nonblock_socket(int fd)
{
    int flags = fcntl(fd,F_GETFL);
    if(flags < 0) return flags;
    
    flags|=O_NONBLOCK;
    if(fcntl(fd,F_SETFL,flags < 0) return -1;
    return 0;
}

// 释放资源
static void free_res(struct ev_loop *loop.ev_io *ws)
{
    des_online_user();
    client_t *client = (client_t*)ws->data;
    if(client == nullptr) fprintf(stderr,"this client is null!") return;
    ev_io_stop(loop,*client->ev_read);
    close(client->fd);
    free(client);
}

// 监听客户端连接回调
static void accept_cb(struct ev_loop *loop,ev_io *w,int revents)
{
    struct sockaddr_in client_addr;
    socklen_t client_len = sizeof(client_addr);
    int client_fd = accept(w->fd,(struct sockaddr*)&client_addr,&client_len);
    if(client_fd == -1)
    {
        fprintf(stderr,"the client fd is null!\n");
        return;
    }

    client_t *client = (client_t*)malloc(sizeof(client_t));
    client->fd = client_fd;
    if(set_nonblock_socket(client->fd) < 0) err(1, "failed to set client socket to non-blocking");
    client->ev_read.data = client;
    ev_io_init(&client->ev_read,read_cb,client->fd,EV_READ);
    ev_io_start(loop,&client->ev_read);
    incr_online_user();
}

// 读入数据回调
static void read_cb(struct ev_loop *loop,ev_io *w,int revents)
{
    
}


int main(int argc,char *argv[])
{
    int ch;
    while((ch = getopt(argc,argv,"p:")) != -1)
    {
        switch(ch)
        {
            case 'p':
                server_port = atoi(optarg);
        }
    }
}

占位符。

Built with Hugo
主题 StackJimmy 设计