欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于C++編寫一個(gè)簡單的服務(wù)器

 更新時(shí)間:2023年03月14日 14:09:40   作者:咩~~  
這篇文章主要為大家詳細(xì)介紹了如何基于C++編寫一個(gè)簡單的服務(wù)器,文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴可以了解一下

本文使用上一期寫的反射類,另外我發(fā)現(xiàn)<WinSock2.h>這個(gè)頭文件里有RegisterClass 這個(gè)結(jié)構(gòu),還有typedef RegisterClass RegisterClassW這句話。。。這都能重復(fù),汗。

先寫個(gè)簡易的controller基類繼承反射基類,之后動(dòng)態(tài)調(diào)用的時(shí)候直接使用父類指針,這樣就能根據(jù)映射表來動(dòng)態(tài)使用對(duì)應(yīng)的成員方法。

#pragma once
#include "Reflex.h"
using namespace myUtil;
class CController :public RObject{
};

先寫個(gè)index控制器,這里我是將聲明和實(shí)現(xiàn)分為兩個(gè)文件寫的,不知道為啥分開寫就報(bào)錯(cuò)LNK2005 和 LNK1169,好在找到了解決辦法,在 屬性->配置屬性->鏈接器->命令行中添加 /FORCE:MULTIPLE 即可

這里我給控制器傳入的參數(shù)是兩個(gè)字符串,這是簡易版本,完全可以照著請求報(bào)文和響應(yīng)報(bào)文實(shí)現(xiàn)兩個(gè)類來完成這部分,之后更新吧
接著說,我直接在響應(yīng)報(bào)文中加入了寫的對(duì)應(yīng)的兩個(gè)html頁面,之后用Postman來測試

#pragma once
#include "CController.h"
using namespace std;
class indexController : public CController
{
public:
    void show();
    void fun();
    void add(int& a, int& b);
    void index(const string& req, string& resp);
    void title(const string& req, string& resp);
    int m_age;
    indexController():m_age(10) {}
};
#include "indexController.h"
#include <iostream>
#include <fstream>
using namespace std;

void indexController::show() {
    cout << "hello world show" << endl;
}
void indexController::fun() {
    cout << "hello world fun" << endl;
}
void indexController::add(int& a, int& b) {
    cout << "hello world add" << endl;
}
void indexController::index(const string& req, string& resp) {
    resp = "";
    resp.append("HTTP/1.1 200 OK\r\n");
    resp.append("content-language:zh-CN");
    resp.append("content-type:text/html;charset=utf-8\r\n\r\n");
    string text = "";
    fstream file;
    file.open("index.html", ios::in);
    if (file.fail()) return;
    while (!file.eof()) {
        char ch;
        file.get(ch);
        text += ch;
    }
    resp.append(text);
}
void indexController::title(const string& req, string& resp) {
    resp = "";
    resp.append("HTTP/1.1 200 OK\r\n");
    resp.append("Content-Type:text/html\r\n\r\n");
    resp.append("{\"name\":\"title\"}");
}

這是一個(gè)專門用來注冊反射的頭文件,在main中直接調(diào)用宏即可

#pragma once
#include "Reflex.h"
#include "indexController.h"
#define REFLEX_DECLARE            \
REGISTER_REFLEX(indexController)\
REGISTER_REFLEX_FIELD(indexController, int, m_age)\
REGISTER_REFLEX_METHOD(indexController, show)\
REGISTER_REFLEX_METHOD(indexController, fun)\
REGISTER_REFLEX_METHOD_ARGS(indexController, add, void, int&, int&)\
REGISTER_REFLEX_METHOD_ARGS(indexController, index, void, string&, string&)\
REGISTER_REFLEX_METHOD_ARGS(indexController, title, void, string&, string&)

這里將映射表設(shè)置為全局變量,可以將服務(wù)作為一個(gè)類,在這個(gè)類中維護(hù)一個(gè)注冊表,再添加一個(gè)方法增加映射,就像springboot中的注釋一樣,下面有反射的測試,可以用函數(shù)名來測試

#include <iostream>
#include <string>
#include <thread>
#include <map>
#include <WinSock2.h>
#include "Util.h"
#include "Singleton.h"
#include "macro.h"
#include "indexController.h"
#pragma comment(lib,"ws2_32.lib")
using namespace std;
using namespace myUtil;

REFLEX_DECLARE
//映射表
map<string, string> mapTable = {
    {"/","index"},
    {"/title","title"}
};
//用來獲取url
vector<string> getStringVectorByChar(const string& source, const char& ch) {
    vector<string> res;
    string temp = "";
    for (char item : source) {
        if (item == ch) {
            res.push_back(temp);
            temp = "";
        }
        else {
            temp += item;
        }
    }
    if (temp != "") res.push_back(temp);
    return res;
}

void threadFunc(SOCKET ServerSocket) {
    char ReceiveBuff[BUFSIZ];
    char SendBuff[BUFSIZ];
    while (true)
    {
        SOCKET ClientSocket;
        SOCKADDR_IN ClientAddr;
        int ClientAddrLen = sizeof(ClientAddr);
        ClientSocket = ::accept(ServerSocket, (SOCKADDR*)&ClientAddr, &ClientAddrLen);
        ZeroMemory(ReceiveBuff, BUFSIZ);
        recv(ClientSocket, ReceiveBuff, BUFSIZ, 0);
        cout << "接收自客戶端數(shù)據(jù):\n" << ReceiveBuff << endl;
        string source(ReceiveBuff);
        string url = getStringVectorByChar(source, ' ')[1];
        //反射使用的地方
        Reflex* factory = Singleton<Reflex>::Instance();
        CController* a = (CController*)factory->createClass("indexController");
        string info = "";
        string req = "";
        string funName = mapTable[url];
        a->Call<void, string&, string&>(funName, req, info);
        //反射使用結(jié)束
        ::send(ClientSocket, info.c_str(), info.size(), 0);
        closesocket(ClientSocket);
    }
}

int main() {
	//測試反射
    //Reflex* factory = Singleton<Reflex>::Instance();
    //CController* a = (CController*)factory->createClass("indexController");
    //while (1) {
    //    string funName = "";
    //    cin >> funName;
    //    a->Call<void,int,int>(funName,1,1);
    //}

    WORD SocketVersion = MAKEWORD(2, 2);
    WSADATA wsd;
    if (WSAStartup(SocketVersion, &wsd) != 0)
    {
        cout << "綁定Socket庫失敗" << endl;
    }
    SOCKET ServerSocket;
    ServerSocket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (ServerSocket == INVALID_SOCKET)
    {
        cout << "創(chuàng)建服務(wù)器套接字失敗" << endl;
        WSACleanup();
        return -1;
    }
    SOCKADDR_IN ServerAddr;
    ServerAddr.sin_family = AF_INET;
    ServerAddr.sin_port = htons(9090);
    ServerAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    int RetVal = ::bind(ServerSocket, (SOCKADDR*)&ServerAddr, sizeof(SOCKADDR_IN));
    if (RetVal == SOCKET_ERROR)
    {
        cout << "套接字綁定失敗" << endl;
        closesocket(ServerSocket);
        WSACleanup();
        return -1;
    }
    RetVal = ::listen(ServerSocket, 2);
    if (RetVal == SOCKET_ERROR)
    {
        cout << "套接字監(jiān)聽失敗" << endl;
        closesocket(ServerSocket);
        WSACleanup();
        return -1;
    }
    thread th(threadFunc, ServerSocket);
    th.join();
    return 0;
}

測試結(jié)果

index

title

以上就是基于C++編寫一個(gè)簡單的服務(wù)器的詳細(xì)內(nèi)容,更多關(guān)于C++服務(wù)器的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 深入探究協(xié)程在C++中的實(shí)現(xiàn)方式

    深入探究協(xié)程在C++中的實(shí)現(xiàn)方式

    協(xié)程可以被看作是計(jì)算機(jī)程序中的獨(dú)立功能塊,它們在執(zhí)行過程中能夠暫停和恢復(fù),與傳統(tǒng)的函數(shù)調(diào)用相比,協(xié)程更像是一種輕量級(jí)的線程,本文我們將深入探究協(xié)程在C++中的實(shí)現(xiàn)方式,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下
    2023-12-12
  • MFC中動(dòng)態(tài)創(chuàng)建控件以及事件響應(yīng)實(shí)現(xiàn)方法

    MFC中動(dòng)態(tài)創(chuàng)建控件以及事件響應(yīng)實(shí)現(xiàn)方法

    這篇文章主要介紹了MFC中動(dòng)態(tài)創(chuàng)建控件以及事件響應(yīng)實(shí)現(xiàn)方法,詳細(xì)講解了MFC中動(dòng)態(tài)創(chuàng)建控件以及事件響應(yīng)的概念與實(shí)現(xiàn)方法,具有一定的實(shí)用價(jià)值,需要的朋友可以參考下
    2014-10-10
  • C++實(shí)現(xiàn)LeetCode(10.正則表達(dá)式匹配)

    C++實(shí)現(xiàn)LeetCode(10.正則表達(dá)式匹配)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(10.正則表達(dá)式匹配),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • Qt實(shí)現(xiàn)俄羅斯方塊

    Qt實(shí)現(xiàn)俄羅斯方塊

    這篇文章主要為大家詳細(xì)介紹了Qt實(shí)現(xiàn)俄羅斯方塊,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • C語言結(jié)構(gòu)體定義的方法匯總

    C語言結(jié)構(gòu)體定義的方法匯總

    結(jié)構(gòu)體是一種工具,用這個(gè)工具可以定義自己的數(shù)據(jù)類型。下面通過本文給大家分享了C語言結(jié)構(gòu)體定義的方法匯總,需要的朋友參考下吧
    2017-12-12
  • vscode編譯運(yùn)行c語言報(bào)錯(cuò)亂碼的解決

    vscode編譯運(yùn)行c語言報(bào)錯(cuò)亂碼的解決

    本文主要介紹了vscode編譯運(yùn)行c語言報(bào)錯(cuò)亂碼,文中通過圖文介紹的的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • C的|、||、&、&&、異或、~、!運(yùn)算符

    C的|、||、&、&&、異或、~、!運(yùn)算符

    這篇文章主要介紹了C的|、||、&、&&、異或、~、!運(yùn)算符,需要的朋友可以參考下
    2014-06-06
  • C語言 用指針作為函數(shù)返回值詳解

    C語言 用指針作為函數(shù)返回值詳解

    本文主要介紹C語言 用指針作為函數(shù)返回值,這里整理了相關(guān)資料及示例代碼,幫助大家學(xué)習(xí)理解此部分知識(shí),有需要的同學(xué)可以參考下
    2016-08-08
  • C++核心編程之內(nèi)存分區(qū)詳解

    C++核心編程之內(nèi)存分區(qū)詳解

    這篇文章主要為大家詳細(xì)介紹了C++核心編程之內(nèi)存分區(qū),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • Windows消息傳遞機(jī)制詳解

    Windows消息傳遞機(jī)制詳解

    這篇文章主要介紹了Windows消息傳遞機(jī)制,有助于讀者更好的理解windows編程的消息機(jī)制,需要的朋友可以參考下
    2014-07-07

最新評(píng)論