精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

如何基于Reactor網絡模型實現業務并測試性能

網絡 網絡管理
這篇文章我們通過實現了一個簡單的HTTP服務來說明如何將Reactor網絡模型應用到業務中去,這是在學校和網上10小時入門C語言里不會講的,但它又非常重要。

對于實現一個http服務來講,一個http請求正常情況下可以分為request和response兩部分,我們可以隨便打開一個網頁,比如:

圖片圖片

我們可以看到,一個http請求,包含Request Header和Response Header,針對HTTP協議的這個特點,我們就可以抽象出http_request和http_response兩個方法,它們分別用于處理HTTP的請求和響應。

那么,最終的流程是從recv_callback接收到數據包,然后調用http_request方法解析HTTP協議,處理相應的業務邏輯,處理完之后將響應結果通過http_response寫入到wbuf中,然后觸發EPOLLOUT事件,最終調用send_callback將wbuf中的數據發送出去,流程大致如下:

圖片圖片

下面我們就來實現一下http_request和http_response,代碼如下:

int http_request(connection_t *conn) {
    // TODO parse http headr and body 
}


int http_response(connection_t *conn) {
    conn->wlen = sprintf(conn->wbuf, 
    "HTTP/1.1 200 OK\\r\\n"
    "Accept-Ranges: bytes\\r\\n"
    "Content-Length: 47\\r\\n"
    "Content-Type: text/html\\r\\n"
    "Date: Sta, 06 Aug 2023 13:16:46 GMT\\r\\n\\r\\n"
    "<html><body><h1>Hello Server</h1></body></html>");


    return conn->wlen;
}

這里省略了http_request中的代碼,本文要關注的重點是如何在基于事件的網絡模型中插入業務代碼,你可能會覺得迷糊,HTTP服務不是也是基礎服務嗎?怎么能叫業務代碼呢?這是相對而言的,對于TCP協議來說,HTTP實際上只是TCP的一個應用,當然算得上是業務代碼了。

上面代碼中定義了一個connection_t類型的參數,實際上這個參數的原型就是conn_channel,其定義如下:

typedef struct conn_channel connection_t;

到這里,不知道你有沒有一種感覺,對于上層的業務代碼來講,它并不關心下層的網絡IO,我們在http_request和http_reponse中并沒有看到直接操作網絡IO的地方,它們只管從對應的rbuf和wbuf中讀和寫,至于數據是怎么收進來的,又是怎么發送出去的并不關心。上一篇文章我們講到網絡IO的分離,通過這一篇文章相信你會有一個更直觀的理解。

我將完整的代碼直接貼在下面了

#include <sys/socket.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <string.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <error.h>


#define BUFFER_LEN 1024


int epfd = 0;


typedef int(*callback)(int);


struct conn_channel {
    int fd;


    char wbuf[BUFFER_LEN];
    int wlen;
    char rbuf[BUFFER_LEN];
    int rlen;


    union {
        callback recv_call;
        callback accept_call;
    } call_t;


    callback send_call;
};


struct conn_channel conn_map[1024] = {0};


typedef struct conn_channel connection_t;


int create_serv(int port) {
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);


    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(struct sockaddr_in));


    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(port);


    int on = 1;
    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));


    int ret = bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr));
    if (ret == -1) {
        perror("socket-bind-fail");
        return -1;
    } 


    listen(sockfd, 1024);


    return sockfd;
}


void make_nonblocking(int fd) {
    fcntl(fd, F_SETFL, O_NONBLOCK);
}


int http_request(connection_t *conn) {
    // TODO parse http headr and body 
}


int http_response(connection_t *conn) {
    conn->wlen = sprintf(conn->wbuf, 
    "HTTP/1.1 200 OK\\r\\n"
    "Accept-Ranges: bytes\\r\\n"
    "Content-Length: 47\\r\\n"
    "Content-Type: text/html\\r\\n"
    "Date: Sta, 06 Aug 2023 13:16:46 GMT\\r\\n\\r\\n"
    "<html><body><h1>Hello Server</h1></body></html>");


    return conn->wlen;
}


int recv_callback(int fd) {
    char *buffer = conn_map[fd].rbuf;
    int idx = conn_map[fd].rlen;


    int count = recv(fd, buffer+idx, BUFFER_LEN - idx, 0);
    if (count == 0) {
        printf("discounnect: %d\\n", fd);
        return -1;
    }


    conn_map[fd].rlen = count;


    // do http request and response
    http_request(&conn_map[fd]);


    http_response(&conn_map[fd]);


    struct epoll_event ev;
    ev.events = EPOLLOUT;
    ev.data.fd = fd;


    epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &ev);


    return count;
}


int send_callback(int fd) {
   int count = send(fd, conn_map[fd].wbuf, conn_map[fd].wlen, 0);
   printf("send-count:%d\\n", count);


   struct epoll_event ev;
   ev.events = EPOLLIN;
   ev.data.fd = fd;


   epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &ev);


   return count; 
}


int accept_callback(int fd) {
    struct sockaddr_in clientaddr;
    socklen_t len = sizeof(clientaddr);


    int clientfd = accept(fd, (struct sockaddr*)&clientaddr, &len);


    struct epoll_event ev;
    ev.events = EPOLLIN;
    ev.data.fd = clientfd;


    conn_map[clientfd].wlen = 0;
    conn_map[clientfd].rlen = 0;
    conn_map[clientfd].call_t.recv_call = recv_callback;
    conn_map[clientfd].send_call = send_callback;


    memset(conn_map[clientfd].wbuf, 0, BUFFER_LEN);
    memset(conn_map[clientfd].rbuf, 0, BUFFER_LEN);


    epoll_ctl(epfd, EPOLL_CTL_ADD, clientfd, &ev);


    return clientfd;
}


int main() {
    int sockfd = create_serv(2048);
    if (sockfd == -1) {
        perror("sockfd-create-fail");
        return -1;
    }


    make_nonblocking(sockfd);


    epfd = epoll_create1(0);


    printf("epfd:%d, sockfd: %d\\n", epfd, sockfd);


    conn_map[sockfd].wlen = 0;
    conn_map[sockfd].rlen = 0;
    conn_map[sockfd].call_t.recv_call = accept_callback;
    conn_map[sockfd].send_call = send_callback;


    memset(conn_map[sockfd].wbuf, 0, BUFFER_LEN);
    memset(conn_map[sockfd].rbuf, 0, BUFFER_LEN);


    struct epoll_event ev;
    ev.events = EPOLLIN;
    ev.data.fd = sockfd;


    epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev);


    struct epoll_event events[1024] = {0};


    while(1) {
        int nready = epoll_wait(epfd, events, 1024, -1);


        int i = 0;
        for (i = 0; i < nready; i++) {
            int connfd = events[i].data.fd;


            if (events[i].events & EPOLLIN) {
                int ret = conn_map[connfd].call_t.recv_call(connfd);            
                printf("epollin-ret: %d\\n", ret); 
            } else if (events[i].events & EPOLLOUT) {
                int count = conn_map[connfd].send_call(connfd);
                printf("send-count: %d\\n", count);
            }
        }
    }
}

上面的代碼200行不到,確包含了Reactor網絡模型的核心思想,以及實現方式,如果有興趣你可以基于此進一步擴展,你也可以參考我們前面網絡編程系列文章,有更加完整的實現。

代碼寫完了,性能究竟如何我們需要進一步驗證,這里推薦一個性能測試工具wrk,wrk是一款開源的性能測試工具,使用C實現,地址:https://github.com/wg/wrk,我準備了兩臺機器,配置如下:

ubuntu20.4      8C8G       192.168.56.2

ubuntu20.4-1   4C4G       192.168.56.3

我們的服務跑在8C8G這臺機器上,另外一臺4C4G的機器用于運行wrk工具進行性能測試。

為了有一個對比,我們首先在8C8G的機器上安裝一個Nginx用來作對比,版本是1.25.4

圖片圖片

然后我們在4C4G的機器上將wrk編譯好,下載好的wrk目錄結構如下:

圖片圖片

可以看到已經有寫好的Makefile了,我們只需要make一下就可以了,make完之后會編譯出一個wrk的二進制文件

圖片圖片

接著,我們將8C8G這臺機器上的Nginx和我們剛剛寫的httpserver都啟動起來,我們的nginx運行在80端口,httpserver運行在2048端口。

接著,我們在4C4G機器上運行wrk先測試nginx,如下:

圖片圖片

接著測試我們自己寫的httpserver

圖片圖片

我們使用wrk開啟50個線程,100個并發持續10秒分別對Nginx和我們自己的httpserver進行了測試,最終的結果我們可以看到,在Nginx沒有任何優化的情況下,我們寫的httpserver明顯比Nginx性能更好。當然,Nginx實際上寫了很多的日志,我們的httpserver幾乎沒有寫什么日志,你可以自己嘗試將Nginx日志關了再對比一下看看結果。

總結

這篇文章我們通過實現了一個簡單的HTTP服務來說明如何將Reactor網絡模型應用到業務中去,這是在學校和網上10小時入門C語言里不會講的,但它又非常重要。

在學習C/C++的過程中,相信很多人都會有這么一種感覺,那就是C/C++語法說起來都會,但就是很難寫出一個完整的項目,個人覺得這是目前國內整個IT教育界的失敗,大部分的課程花了非常大的篇幅講if-else,甚至將各種變量類型都講出花來了,但就是不告訴你一個完整的項目該如何寫。

責任編輯:武曉燕 來源: 程序員班吉
相關推薦

2024-08-16 21:30:00

IO網絡網絡通信

2023-12-05 17:44:24

reactor網絡

2024-04-18 09:34:28

Reactor項目異步編程

2019-01-15 10:54:03

高性能ServerReactor

2020-12-01 07:08:23

Linux網絡I

2023-09-13 14:45:14

性能測試開發

2011-05-16 14:13:04

模型測試

2021-09-21 09:01:19

網絡安全疫情數據

2009-12-30 10:31:04

配置NAT網絡

2021-06-02 10:00:30

云網絡性能測試

2016-11-07 18:26:39

IT可視化

2009-03-27 09:59:00

2022-05-17 08:53:26

TPS性能測試

2024-04-15 13:51:03

模型LLMLLMs

2022-01-04 11:11:32

Redis單線程Reactor

2020-06-17 16:38:22

Rust業務架構

2012-05-08 13:36:55

2012-07-27 15:28:09

SingleSON華為

2018-09-05 09:32:42

高性能網絡模型

2022-05-26 10:12:21

前端優化測試
點贊
收藏

51CTO技術棧公眾號

欧美大片顶级少妇| 日本一区二区三级电影在线观看 | eeuss影院在线播放| 热久久久久久久| 欧美激情一区二区三区高清视频 | 亚洲免费观看高清完整版在线观看熊| 国产精品jizz视频| 天天爱天天做天天爽| 亚洲a一区二区三区| 精品亚洲一区二区| 国产老头和老头xxxx×| 欧美男体视频| 亚洲自拍与偷拍| 性刺激综合网| 色欲久久久天天天综合网| 免费高清成人在线| 6080yy精品一区二区三区| 性生交大片免费全黄| 欧美日韩麻豆| 日韩欧美国产精品一区| 波多野结衣爱爱| 久久久久久久久久久9不雅视频| 精品粉嫩超白一线天av| 成人亚洲精品777777大片| 免费不卡av| 国产精品久久久久久久浪潮网站| 久久国产精品一区二区三区| 99热这里只有精品3| 日韩精品欧美成人高清一区二区| 欧美黑人一级爽快片淫片高清| 日本免费www| 特级西西444www大精品视频| 国产亚洲精品码| 久久中文亚洲字幕| 亚洲精品一区二区三区不| wwwxxxx在线观看| 成人亚洲综合| 色综合中文综合网| 国产又黄又爽免费视频| 手机看片1024日韩| 国产风韵犹存在线视精品| 成人在线播放av| 在线观看黄色国产| 午夜在线一区二区| 91精品国产一区| 久久精品99国产精| 国内精品福利| 日韩最新在线视频| 午夜时刻免费入口| 国产亚洲一区二区三区啪| 精品电影一区二区三区| xfplay5566色资源网站| 中文字幕区一区二区三| 欧美大片免费久久精品三p| 在线观看中文av| 成人动漫视频在线观看| 欧美久久久久久蜜桃| 日本高清一区二区视频| 欧美视频第一| 正在播放亚洲一区| 五月激情五月婷婷| 欧美1区2区3| 欧美成人三级电影在线| 伊人网综合视频| 人人精品亚洲| 亚洲色图美腿丝袜| 四虎地址8848| 国产一区二区中文| 午夜精品久久久99热福利| 国产成人亚洲精品自产在线| 国产精品人人爽人人做我的可爱| 欧美一乱一性一交一视频| 日韩不卡在线播放| 免费高清在线一区| 5g国产欧美日韩视频| 亚洲毛片欧洲毛片国产一品色| 成人av网站在线| 另类视频在线观看+1080p| 国产一二三区在线| 中文字幕一区二区不卡| 亚洲视频sss| 黄a在线观看| 亚洲成人激情av| 国产极品尤物在线| 国产精品毛片久久久久久久久久99999999| 欧美日韩亚洲不卡| 日韩av成人网| 色吊丝在线永久观看最新版本| 国产欧美精品在线观看| 四虎4hu永久免费入口| av2020不卡| 欧美在线播放高清精品| 韩国三级在线播放| 美女精品一区最新中文字幕一区二区三区 | 欧美一级特黄aaaaaa在线看片| 国产极品人妖在线观看| 色噜噜久久综合| 男女视频在线观看网站| 五月天亚洲色图| 久久久成人精品视频| 99热在线观看免费精品| 美女任你摸久久| 国产一区二区高清视频| 日本网站在线免费观看视频| 亚洲一卡二卡三卡四卡| 免费看污污网站| 黄色成人美女网站| 久久综合免费视频| www.久久精品视频| 福利一区福利二区| 在线观看亚洲视频啊啊啊啊| 天堂av在线| 欧美成人官网二区| 农村老熟妇乱子伦视频| 久久国产精品亚洲77777| 3d蒂法精品啪啪一区二区免费| 九九九伊在人线综合| 一区二区三区中文免费| 亚洲少妇久久久| 一区二区小说| 国内精品免费午夜毛片| av在线免费在线观看| 欧美国产精品久久| 国产亚洲精品网站| 9l视频自拍蝌蚪9l视频成人| 久久精品国产欧美亚洲人人爽| 69国产精品视频免费观看| 丁香婷婷深情五月亚洲| 在线观看免费黄色片| 国产成人毛片| 亚洲人成啪啪网站| av大全在线观看| av电影天堂一区二区在线| 欧美少妇在线观看| 成人在线精品| 久久久国产成人精品| 在线观看xxxx| 国产精品欧美久久久久无广告| 97超碰青青草| 亚洲三级网址| 欧美一二三视频| 视频午夜在线| 欧美色播在线播放| 亚洲精品视频大全| 亚洲影视综合| 欧美精品一区在线| 丝袜美腿诱惑一区二区三区| 国产网站欧美日韩免费精品在线观看| 欧美日韩综合在线观看| 99精品一区二区| 日本毛片在线免费观看| 亚洲大片精品免费| 国产精品成人免费电影| av电影在线网| 在线不卡的av| 青青操视频在线播放| 国产精品18久久久久久久久| 久久久国内精品| 白嫩白嫩国产精品| 国产91精品高潮白浆喷水| 午夜视频在线免费播放| 欧美色视频日本版| 老熟妇一区二区| 精品中文字幕一区二区| 国产成人免费高清视频| 国产精品午夜av| 欧美专区在线观看| av电影在线观看| 制服丝袜av成人在线看| 国产在线欧美在线| 91免费国产视频网站| 国产免费视频传媒| 天天射综合网视频| 成人激情av| 精品91久久| www.精品av.com| 丰满人妻一区二区三区四区53| 午夜精彩视频在线观看不卡| 亚洲激情视频小说| 激情久久五月天| 欧美亚洲黄色片| 国产精品午夜一区二区三区| 国产在线观看精品一区二区三区| 久久av色综合| 亚洲深夜福利在线| 精品国产亚洲av麻豆| 婷婷一区二区三区| 男人天堂资源网| 成人精品免费网站| 国产精品久久a| 欧美日韩亚洲三区| 日本高清不卡一区二区三| 91精品网站在线观看| 97在线精品国自产拍中文| 天堂地址在线www| 亚洲爱爱爱爱爱| 伊人精品在线视频| 精品福利在线视频| 91高清免费看| 久久奇米777| 佐佐木明希电影| 久久精品国产网站| 日韩中文字幕在线不卡| 精品视频99| 国产日韩二区| 国产一区二区三区黄网站| 日韩av电影国产| 波多野在线观看| 久久久av电影| 中文字幕在线播放| 亚洲欧美色图片| 免费的黄色av| 91精品国产乱| 中文字幕福利视频| 欧美日韩中文在线观看| 在线观看成人毛片| 国产精品国产三级国产专播品爱网 | 久久精品视频6| 中文字幕中文字幕一区二区| 草草影院第一页| www.一区二区| 国产chinesehd精品露脸| 老色鬼精品视频在线观看播放| 97在线播放视频| 一本久道久久久| 久久国产午夜精品理论片最新版本| 色88久久久久高潮综合影院| 欧美二区在线| 同性恋视频一区| 成人自拍爱视频| 蜜桃精品一区二区三区| 国产在线播放91| 青青国产精品| 国产一区二区在线播放| 性欧美freehd18| 国产国语videosex另类| 国产精品粉嫩| 日本精品一区二区三区在线播放视频| 国产传媒在线| 97avcom| 国产免费拔擦拔擦8x在线播放| 欧美激情一级精品国产| 欧美videosex性极品hd| 欧美乱大交做爰xxxⅹ性3| 黄色av网站在线播放| 久久久国产精品亚洲一区| 幼a在线观看| 日韩一区二区三区国产| 久久精品视频免费看| 久久久成人的性感天堂| 在线观看中文字幕的网站| 欧美乱大交xxxxx| 第四色日韩影片| 91成人精品网站| 二区三区不卡| 国产精品国产三级国产aⅴ浪潮| 婷婷激情一区| 国产精品欧美日韩久久| 欧美一级做一级爱a做片性| 国产在线观看91精品一区| 久久丁香四色| 国产日韩亚洲精品| 免费看av成人| 亚洲一区二区三区乱码| 久久精品久久久| 97超碰在线人人| 老司机一区二区三区| 男女男精品视频站| 国产福利一区二区| 免费的av网站| 亚洲国产精品精华液ab| 三级全黄做爰视频| 亚洲国产精品久久艾草纯爱| 国产高潮久久久| 欧美精品久久99| 蜜臀久久精品久久久久| 亚洲无限av看| 黄色网页网址在线免费| 欧美精品久久久久久久免费观看 | 欧美日韩国产在线| 性高潮视频在线观看| 欧美一级淫片007| 香蕉视频成人在线| 色婷婷成人综合| 高清精品在线| 91久久在线播放| 欧美一级二级三级视频| 一区二区免费在线视频| 精品91在线| 日韩欧美国产片| 成人av在线网| 熟女少妇a性色生活片毛片| 亚洲国产美国国产综合一区二区| 波多野结衣爱爱| 精品精品欲导航| av中文字幕一区二区三区| 久久久久亚洲精品| 四虎国产精品免费久久5151| 国产精品视频一区二区三区经| 第一社区sis001原创亚洲| 成人免费毛片在线观看| 久久精品72免费观看| 久久久国产精品无码| 亚洲天堂中文字幕| 日本免费精品视频| 亚洲电影免费观看高清完整版在线观看| 国产人成在线观看| 91禁国产网站| 日韩欧美一级| 亚洲视频导航| 日韩二区三区在线观看| 亚洲一区二区在线免费| 亚洲欧美色一区| 中文字幕人妻丝袜乱一区三区| 亚洲国语精品自产拍在线观看| 含羞草www国产在线视频| 国产成人涩涩涩视频在线观看| av日韩在线播放| 91制片厂免费观看| 毛片av一区二区| 欧美另类z0zx974| 欧美日韩国产精品一区| 成人久久精品人妻一区二区三区| 精品国产视频在线| 精品久久99| 亚洲国产精品一区在线观看不卡| 午夜在线a亚洲v天堂网2018| 91九色蝌蚪porny| 亚洲精品成人在线| 国产三区在线播放| 日日噜噜噜夜夜爽亚洲精品| 吞精囗交69激情欧美| 免费成人在线观看av| 国产欧美在线| 国产精品嫩草av| 精品久久久香蕉免费精品视频| www.夜夜爽| 久久久久观看| 免费看欧美一级片| 国产99精品国产| 国产一级做a爱免费视频| 精品sm捆绑视频| 国产理论在线| 国产v亚洲v天堂无码| 国产精品vip| 国产精品熟妇一区二区三区四区 | 国产一级二级三级视频| 欧美视频在线一区| 在线免费观看黄色av| 国产美女高潮久久白浆| 日韩欧美中字| 一级黄色大片儿| 亚洲电影在线免费观看| 婷婷色在线视频| 欧美一二三视频| 日韩欧美三级| 搡的我好爽在线观看免费视频| 亚洲精品高清在线观看| 亚洲第一精品网站| 91国内在线视频| 精品日韩在线| 一级做a爱视频| 性欧美疯狂xxxxbbbb| 欧美亚洲日本| 国产精品久久久久久久久久三级| 成人高清av| 日本在线视频播放| 五月综合激情日本mⅴ| 蜜桃视频在线观看网站| 国产精品久久久久久婷婷天堂| 久久在线免费| zjzjzjzjzj亚洲女人| 色综合天天在线| 日本精品在线| 国产高清精品一区二区三区| 亚洲专区免费| 可以免费看av的网址| 日韩你懂的在线播放| 欧美三级网站| 亚洲一区在线直播| 成人免费高清视频| 好吊色在线视频| 欧美剧在线观看| 亚洲精品一级二级三级| 中文字幕成人在线视频| 亚洲午夜国产一区99re久久| 国产视频精选在线| 高清av免费一区中文字幕| 玖玖精品视频| 青春草免费视频| 在线日韩中文字幕| 超碰成人在线观看| 污污动漫在线观看| 亚州成人在线电影| 国内精品久久久久久野外| 久久免费看av| 国产精品主播直播| 欧美一区免费看| 久久久久久久成人| 国产精品成人一区二区不卡|