<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ## 1) 框架結構 ![](https://img.kancloud.cn/f3/cc/f3cc8ba143e5e0f612a13f507c396fc4_1082x687.png) ## 2) Lars Reactor V0.1開發 ? 我們首先先完成一個最基本的服務器開發模型,封裝一個`tcp_server`類。 > lars_reactor/include/tcp_server.h ```c #pragma once #include <netinet/in.h> class tcp_server { public: //server的構造函數 tcp_server(const char *ip, uint16_t port); //開始提供創建鏈接服務 void do_accept(); //鏈接對象釋放的析構 ~tcp_server(); private: int _sockfd; //套接字 struct sockaddr_in _connaddr; //客戶端鏈接地址 socklen_t _addrlen; //客戶端鏈接地址長度 }; ``` ? 在tcp_server.cpp中完成基本的功能實現,我們在構造函數里將基本的socket創建服務器編程寫完,然后提供一個阻塞的do_accept()方法。 > lars_reactor/src/tcp_server.cpp ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include <unistd.h> #include <signal.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <arpa/inet.h> #include <errno.h> #include "tcp_server.h" //server的構造函數 tcp_server::tcp_server(const char *ip, uint16_t port) { bzero(&_connaddr, sizeof(_connaddr)); //忽略一些信號 SIGHUP, SIGPIPE //SIGPIPE:如果客戶端關閉,服務端再次write就會產生 //SIGHUP:如果terminal關閉,會給當前進程發送該信號 if (signal(SIGHUP, SIG_IGN) == SIG_ERR) { fprintf(stderr, "signal ignore SIGHUP\n"); } if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) { fprintf(stderr, "signal ignore SIGPIPE\n"); } //1. 創建socket _sockfd = socket(AF_INET, SOCK_STREAM /*| SOCK_NONBLOCK*/ | SOCK_CLOEXEC, IPPROTO_TCP); if (_sockfd == -1) { fprintf(stderr, "tcp_server::socket()\n"); exit(1); } //2 初始化地址 struct sockaddr_in server_addr; bzero(&server_addr, sizeof(server_addr)); server_addr.sin_family = AF_INET; inet_aton(ip, &server_addr.sin_addr); server_addr.sin_port = htons(port); //2-1可以多次監聽,設置REUSE屬性 int op = 1; if (setsockopt(_sockfd, SOL_SOCKET, SO_REUSEADDR, &op, sizeof(op)) < 0) { fprintf(stderr, "setsocketopt SO_REUSEADDR\n"); } //3 綁定端口 if (bind(_sockfd, (const struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) { fprintf(stderr, "bind error\n"); exit(1); } //4 監聽ip端口 if (listen(_sockfd, 500) == -1) { fprintf(stderr, "listen error\n"); exit(1); } } //開始提供創建鏈接服務 void tcp_server::do_accept() { int connfd; while(true) { //accept與客戶端創建鏈接 printf("begin accept\n"); connfd = accept(_sockfd, (struct sockaddr*)&_connaddr, &_addrlen); if (connfd == -1) { if (errno == EINTR) { fprintf(stderr, "accept errno=EINTR\n"); continue; } else if (errno == EMFILE) { //建立鏈接過多,資源不夠 fprintf(stderr, "accept errno=EMFILE\n"); } else if (errno == EAGAIN) { fprintf(stderr, "accept errno=EAGAIN\n"); break; } else { fprintf(stderr, "accept error"); exit(1); } } else { //accept succ! //TODO 添加心跳機制 //TODO 消息隊列機制 int writed; char *data = "hello Lars\n"; do { writed = write(connfd, data, strlen(data)+1); } while (writed == -1 && errno == EINTR); if (writed > 0) { //succ printf("write succ!\n"); } if (writed == -1 && errno == EAGAIN) { writed = 0; //不是錯誤,僅返回0表示此時不可繼續寫 } } } } //鏈接對象釋放的析構 tcp_server::~tcp_server() { close(_sockfd); } ``` ? 好了,現在回到`lars_reactor`目錄下進行編譯。 ```bash $~/Lars/lars_reactor/ $make ``` 在`lib`下,得到了庫文件。 接下來,做一下測試,寫一個簡單的服務器應用. ```bash $cd ~/Lars/lars_reactor/example $mkdir lars_reactor_0.1 $cd lars_reactor_0.1 ``` > lars_reactor/example/lars_reactor_0.1/Makefile ```makefile CXX=g++ CFLAGS=-g -O2 -Wall -fPIC -Wno-deprecated INC=-I../../include LIB=-L../../lib -llreactor OBJS = $(addsuffix .o, $(basename $(wildcard *.cc))) all: $(CXX) -o lars_reactor $(CFLAGS) lars_reactor.cpp $(INC) $(LIB) clean: -rm -f *.o lars_reactor ``` > lars_reactor/example/lars_reactor_0.1/lars_reactor.cpp ```c #include "tcp_server.h" int main() { tcp_server server("127.0.0.1", 7777); server.do_accept(); return 0; } ``` ? 接下來,我們make進行編譯,編譯的時候會指定鏈接我們剛才生成的liblreactor.a庫。 服務端: ```bash $ ./lars_reactor begin accept ``` 客戶端: ```bash $nc 127.0.0.1 7777 hello Lars ``` 得到了服務器返回的結果,那么我們最開始的0.1版本就已經搭建完了,但是實際上這并不是一個并發服務器,萬里長征才剛剛開始而已。 --- ### 關于作者: 作者:`Aceld(劉丹冰)` mail: [danbing.at@gmail.com](mailto:danbing.at@gmail.com) github: [https://github.com/aceld](https://github.com/aceld) 原創書籍: [http://www.hmoore.net/@aceld](http://www.hmoore.net/@aceld) ![](https://img.kancloud.cn/b0/d1/b0d11a21ba62e96aef1c11d5bfff2cf8_227x227.jpg) >**原創聲明:未經作者允許請勿轉載, 如果轉載請注明出處**
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看