国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

談?wù)刲inux網(wǎng)絡(luò)編程中的應(yīng)用層協(xié)議定制、Json序列化與反序列化那些事

這篇具有很好參考價(jià)值的文章主要介紹了談?wù)刲inux網(wǎng)絡(luò)編程中的應(yīng)用層協(xié)議定制、Json序列化與反序列化那些事。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

一、序列化與反序列化

由于socket api的接口,在讀寫數(shù)據(jù)的時(shí)候是以字符串的方式發(fā)送接收的,如果需要傳輸結(jié)構(gòu)化的數(shù)據(jù),就需要制定一個(gè)協(xié)議
談?wù)刲inux網(wǎng)絡(luò)編程中的應(yīng)用層協(xié)議定制、Json序列化與反序列化那些事
結(jié)構(gòu)化數(shù)據(jù)在發(fā)送到網(wǎng)絡(luò)中之前需要完成序列化
接收方收到的是序列字節(jié)流,需要完成反序列化才能使用(如ChatInfo._name)

二、應(yīng)用層協(xié)議如何定制

當(dāng)我們進(jìn)行網(wǎng)絡(luò)通信的的時(shí)候,一端發(fā)送時(shí)構(gòu)造的數(shù)據(jù), 在另一端能夠正確的進(jìn)行解析(完整的讀到一條報(bào)文), 就是可行的的. 這種約定, 就是 應(yīng)用層協(xié)議

如何保證讀到的消息是一個(gè)完整的請(qǐng)求
TCP是面向字節(jié)流的,無法直接讀取,需要明確報(bào)文和報(bào)文的邊界,常見的方法有.定長:固定報(bào)文長度、特殊符號(hào):在報(bào)文前面加上一個(gè)字段、自描述

三、網(wǎng)絡(luò)通信中數(shù)據(jù)流動(dòng)的本質(zhì)

談?wù)刲inux網(wǎng)絡(luò)編程中的應(yīng)用層協(xié)議定制、Json序列化與反序列化那些事
我們調(diào)用的所有的發(fā)送函數(shù)(read),不是把數(shù)據(jù)發(fā)送到網(wǎng)絡(luò)中,發(fā)送函數(shù)的本質(zhì)是拷貝函數(shù)(將數(shù)據(jù)從應(yīng)用層緩沖區(qū)拷貝到發(fā)送緩沖區(qū))

  1. Client->Server:tcp發(fā)送的本質(zhì),其實(shí)就是將數(shù)據(jù)從Client的發(fā)送緩沖區(qū)拷貝到Server的接收緩沖區(qū)
  2. 反過來Server->CLient:其實(shí)就是將數(shù)據(jù)從Server的發(fā)送緩沖區(qū)拷貝到
    Client的接收緩沖區(qū)
  3. 這也說明了網(wǎng)絡(luò)編程(套接字編程)是全雙工的

四、網(wǎng)絡(luò)版計(jì)算器編寫

有了前面的知識(shí),下面實(shí)現(xiàn)一個(gè)服務(wù)器版的計(jì)算器. 我們需要客戶端把要計(jì)算的兩個(gè)數(shù)發(fā)過去, 然后由服務(wù)器進(jìn)行計(jì)算, 最后再把結(jié)果返回給客戶端

4.1 業(yè)務(wù)流程

在完成服務(wù)器與客戶端正常通信的基礎(chǔ)上完成一次請(qǐng)求與響應(yīng)的流程
客戶端:

  1. 從鍵盤讀取數(shù)據(jù)并調(diào)用ParseLine()函數(shù)將輸入的數(shù)據(jù)轉(zhuǎn)換成類似“123+123"的格式
  2. 序列化字符串,將結(jié)構(gòu)化的數(shù)據(jù)轉(zhuǎn)化成用于網(wǎng)絡(luò)通信的一個(gè)大字符串,調(diào)用請(qǐng)求類的序列化函數(shù)enLength()
  3. 添加報(bào)頭:通過協(xié)議定制的規(guī)則,將"x op y"---->“content_len”\r\n"x op y"\r\n
  4. 向服務(wù)端發(fā)送已經(jīng)構(gòu)建好的報(bào)文
  5. 阻塞讀取服務(wù)端處理后的響應(yīng)數(shù)據(jù)
    等待服務(wù)器發(fā)送響應(yīng)報(bào)文
  6. 讀取到一個(gè)完整的報(bào)文
  7. 調(diào)用協(xié)議方法去掉報(bào)頭并將結(jié)果輸出到text里面
  8. 對(duì)收到的響應(yīng)正文序列化填充到響應(yīng)類對(duì)象的成員變量里
  9. 通過正常調(diào)用,訪問處理后的結(jié)果
  10. 發(fā)送新的請(qǐng)求

服務(wù)端:

  1. 創(chuàng)建子進(jìn)程去執(zhí)行任務(wù)
  2. 死循環(huán)式的讀取來自客戶端的報(bào)文,調(diào)用recvRequest,讀取一個(gè)完整的請(qǐng)求放入輸出型參數(shù)text里面
  3. 根據(jù)協(xié)議定制,調(diào)用deLength()去掉報(bào)文的報(bào)頭,得到有效數(shù)據(jù)req_str
  4. 將來自網(wǎng)絡(luò)的字符串通過調(diào)用請(qǐng)求類的反序列化轉(zhuǎn)化成結(jié)構(gòu)化的數(shù)據(jù),請(qǐng)求類對(duì)象成員完成賦值
  5. 通過回調(diào)函數(shù)(一個(gè)輸入型參數(shù)(請(qǐng)求類對(duì)象),一個(gè)輸出型參數(shù)(響應(yīng)類對(duì)象))傳遞兩個(gè)類對(duì)象,將計(jì)算結(jié)果賦值給響應(yīng)類的成員變量
  6. 開始將處理結(jié)果返回給客戶端,調(diào)用響應(yīng)類中的序列化方法將結(jié)構(gòu)化數(shù)據(jù)轉(zhuǎn)換成一個(gè)大字符串
  7. 對(duì)大字符串添加報(bào)頭構(gòu)建成一個(gè)完整的報(bào)文,發(fā)送給客戶端
  8. 服務(wù)端等待新的請(qǐng)求…

4.2 核心代碼

Protocol.hpp包含了協(xié)議定制函數(shù)、請(qǐng)求響應(yīng)序列化與反序列化函數(shù)、完整報(bào)文獲取函數(shù)

#pragma once
#include <iostream>
#include <string>
#include <cstring>
#include <jsoncpp/json/json.h>

using namespace std;

#define SEP " "             // 分隔符
#define SEP_LEN strlen(SEP) // 分隔符長度,不能用sizeof

#define LINE_SEP "\r\n"

#define LINE_SEP_LINE strlen(LINE_SEP)

enum
{
    OK = 0,
    DIV_ZERO,
    MOD_ZERO,
    OP_ERROR
};

// 協(xié)議定制:給報(bào)文段加一個(gè)特殊字段:有效載荷的長度

//                報(bào)頭            有效載荷
// 
//"exitcode result"---->"content_len"\r\n"exitcode result"\r\n----
std::string enlength(const std::string &text)
{



    // text就是"x op y"
    string send_string = std::to_string(text.size()); // content_len
    send_string += LINE_SEP;
    send_string += text;
    send_string += LINE_SEP;

    return send_string;
}

// 去掉報(bào)頭,提取有效載荷
//"content_len"\r\n"exitcode result"\r\n---->exitcode result
bool delength(const std::string &package, std::string *text)
{


    auto pos = package.find(LINE_SEP);
    if (pos == string::npos)
        return false;
    // 提取報(bào)頭字符串
    string text_len_string = package.substr(0, pos);
    // 將報(bào)頭信息轉(zhuǎn)化成字符串
    int text_len = std::stoi(text_len_string);
    // 提取有效載荷
    *text = package.substr(pos + LINE_SEP_LINE, text_len);

    return true;
}

// 請(qǐng)求
class Request
{
public:
    Request()
        : x_(0), y_(0), op_(0)
    {
    }
    Request(int x, int y, char op)
        : x_(x), y_(y), op_(op)
    {
    }
    // 序列化
    bool serialize(std::string *out)
    {
#ifdef MYSELF        
        // 將結(jié)構(gòu)化數(shù)據(jù)轉(zhuǎn)化成-->"x op y"

        out->clear();
        std::string x_string = std::to_string(x_);
        std::string y_string = std::to_string(y_);
        *out = x_string;
        *out += SEP;
        *out += op_;
        *out += SEP;
        *out += y_string;
#else
        Json::Value root;//定義一個(gè)萬能對(duì)象
        root["first"]=x_;
        root["second"]=y_;
        root["oper"]=op_;

        Json::FastWriter writer;
        *out=writer.write(root);

#endif        
        return true;
    }

    // 反序列化
    bool deserialize(const std::string &in)
    {
 #ifdef MYSELF         
        //"x op yyy";
        auto left = in.find(SEP);
        auto right = in.rfind(SEP);

        if (left == std::string::npos || right == std::string::npos)
            return false;
        if (left == right)
            return false;

        // 截取子串
        if (right - (left + SEP_LEN) != 1)
            return false;

        std::string x_string = in.substr(0, left);         // 定位到x
        std::string y_string = in.substr(right + SEP_LEN); // 定位到y(tǒng)yyy

        if (x_string.empty())
            return false;
        if (y_string.empty())
            return false;

        x_ = std::stoi(x_string);
        y_ = std::stoi(y_string);
        op_ = in[left + SEP_LEN]; // 截取op
#else
        Json::Value root;
        Json::Reader reader;
        reader.parse(in,root);//將解析出來的值放進(jìn)root里面
        x_=root["first"].asInt();//將val轉(zhuǎn)化成整數(shù)
        y_=root["second"].asInt();
        op_=root["oper"].asInt();
#endif
        return true;
    }

public:
    int x_;
    int y_;
    char op_;
};

// 響應(yīng)
class Response
{
public:
    Response()
        : exitcode_(0), result_(0)
    {
    }
    Response(int exitcode, int result)
        : exitcode_(exitcode), result_(result)
    {
    }

    // 序列化
    bool serialize(std::string *out)
    {
#ifdef MYSELF
        // 清空字符串
        out->clear();
        // 將退出碼和結(jié)果轉(zhuǎn)換成字符串
        string ec_string = std::to_string(exitcode_);
        string res_string = std::to_string(result_);

        // 合并字符
        *out = ec_string;
        *out += SEP;
        *out += res_string;
#else
        Json::Value root;
        root["exitcode"]=exitcode_;
        root["result"]=result_;
        Json::FastWriter writer;
        *out=writer.write(root);
        

#endif
        return true;
    }

    // 反序列化
    bool deserialize(const std::string &in)
    {

#ifdef MYSELF        
        //"exitcode result"
        auto mid = in.find(SEP);
        if (mid == std::string::npos)
            return false;
        // 截取字符串
        string ec_string = in.substr(0, mid);
        string res_string = in.substr(mid + SEP_LEN);

        if (ec_string.empty() || res_string.empty())
            return false;

        // 寫入退出碼和結(jié)果
        exitcode_ = std::stoi(ec_string);
        result_ = std::stoi(res_string);
#else
        Json::Reader reader;
        Json::Value root;
        reader.parse(in,root);
        exitcode_=root["exitcode"].asInt();
        result_=root["result"].asInt();
#endif
        return true;
    }

public:
    int exitcode_; // 0成功,!0錯(cuò)誤
    int result_;   // 計(jì)算結(jié)果
};

// 讀取一個(gè)完整的請(qǐng)求放入text里面
//"content_len"\r\n"x op y"\r\n"content_len"\r\n"x op y"\r\n
bool recvRequest(int sock, std::string &inbuffer, string *text)
{
    char buffer[1024];
    while (true)
    {
        ssize_t n = recv(sock, buffer, sizeof(buffer) - 1, 0);
        if (n > 0)
        {
            buffer[n] = 0;
            inbuffer += buffer;

            // 邊讀邊處理
            auto pos = inbuffer.find(LINE_SEP);
            // 如果沒有讀到\r\n,接著去讀
            if (pos == string::npos)
                continue;
            // 走到這已經(jīng)讀到了content_len,知道了有效載荷長度

            string text_len_string = inbuffer.substr(0, pos); // 報(bào)頭
            int text_len = std::stoi(text_len_string);        // 正文長度
            int total_len = text_len_string.size() + 2 * LINE_SEP_LINE + text_len;
            std::cout << "處理前#inbuffer: \n"
                      << inbuffer << endl;
            if (inbuffer.size() < total_len)
            {
                std::cout << "你輸入的消息,沒有嚴(yán)格遵守我們的協(xié)議,正在等待后續(xù)的內(nèi)容, continue" << std::endl;
                continue; // 沒有讀到一個(gè)完整的報(bào)文
            }
            // 至少有一個(gè)報(bào)文
            *text = inbuffer.substr(0, total_len);
            inbuffer.erase(0, total_len);
            std::cout << "處理后#inbuffer: \n"
                      << inbuffer << endl;

            break;
        }
        else
            return false;
    }

    return true;
}

服務(wù)端響應(yīng)流程

void handlerEnter(int sock, func_t func)
    {
        string inuffer;//將所有信息寫入到inbuffer
        while(true)
        {
            // 1.讀?。?content_len"\r\n"x op y"\r\n
            // 1.1 保證讀到的消息是【一個(gè)完整】的請(qǐng)求
            std::string req_text; // 輸出型參數(shù),整個(gè)報(bào)文
            if (!recvRequest(sock, inuffer,&req_text))
                return;
            std::cout<<"帶報(bào)頭的請(qǐng)求:\n"<<req_text<<endl;    
            // 1.2 去報(bào)頭,只要正文
            std::string req_str; // 正文部分
            if (!delength(req_text, &req_str))
                return;
            std::cout<<"去掉報(bào)頭后的正文:\n"<<req_str<<endl; 

            // 2.反序列化
            // 2.1 得到一個(gè)結(jié)構(gòu)化對(duì)象,對(duì)象中的成員已經(jīng)被填充
            Request req;
            if (!req.deserialize(req_str))
                return;

            // 3.處理數(shù)據(jù)---------業(yè)務(wù)邏輯
            // 3.1 得到一個(gè)結(jié)構(gòu)化的響應(yīng),resp成員已被填充
            Response resp;
            func(req, resp); // 回調(diào)

            // 4.對(duì)響應(yīng)Response,序列化
            // 4.1 得到一個(gè)字符串
            std::string resp_str;
            resp.serialize(&resp_str); // 輸出型參數(shù),將序列化結(jié)果寫入resp_str
            std::cout<<"計(jì)算完成,序列化響應(yīng): "<<resp_str<<endl;

            // 5.然后發(fā)送響應(yīng)
            // 5.1添加協(xié)議報(bào)頭,構(gòu)建成一個(gè)完整的報(bào)文
            std::string send_string = enlength(resp_str);
            std::cout<<"構(gòu)建帶報(bào)頭的響應(yīng)正文: \n"<<send_string<<endl;

            // 發(fā)送
            send(sock, send_string.c_str(), send_string.size(), 0); // 有問題
            std::cout<<"發(fā)送響應(yīng)報(bào)文成功: \n"<<endl;
        }
    }

客戶端請(qǐng)求流程

		void run()
        {
            struct sockaddr_in server;
            memset(&server, 0, sizeof(server));
            server.sin_family = AF_INET;
            server.sin_port = htons(clientport_);
            server.sin_addr.s_addr = inet_addr(clientip_.c_str());

            // 發(fā)起鏈接
            if (connect(sockfd_, (struct sockaddr *)&server, sizeof(server)) != 0)
            {
                std::cerr << "connect create error" << endl;
            }
            else
            {
                string msg;
                string inbuffer;
                while (true)
                {
                    cout << "mycal>>> ";
                    std::getline(std::cin, msg);
                    Request req = ParseLine(msg); // 從鍵盤提取字符串

                    string content;
                    // 序列化結(jié)構(gòu)數(shù)據(jù)
                    req.serialize(&content);
                    // 添加報(bào)頭
                    string send_string = enlength(content);
                    // 發(fā)送數(shù)據(jù)
                    send(sockfd_, send_string.c_str(), send_string.size(), 0);
                    

                    // 接收響應(yīng)報(bào)文
                    
                    string package, text;
                    if (!recvRequest(sockfd_,inbuffer,&package))
                        continue;
                    
                    //去掉報(bào)頭,獲取正文放在text里面   
                    if(!delength(package,&text)) continue;
                    

                    //將收到的響應(yīng)正文反序列化
                    Response resp;
                    resp.deserialize(text);
                    std::cout << "exitCode: " << resp.exitcode_ << std::endl;
                    std::cout << "result: " << resp.result_ << std::endl;     
                }
            }
        }

正常輸入輸出顯示如下圖
談?wù)刲inux網(wǎng)絡(luò)編程中的應(yīng)用層協(xié)議定制、Json序列化與反序列化那些事

以上只是提供了幾個(gè)核心的代碼塊,完整版代碼可以去我的Gitee,代碼注釋詳細(xì),希望對(duì)你有所幫助文章來源地址http://www.zghlxwxcb.cn/news/detail-459830.html

到了這里,關(guān)于談?wù)刲inux網(wǎng)絡(luò)編程中的應(yīng)用層協(xié)議定制、Json序列化與反序列化那些事的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 「網(wǎng)絡(luò)編程」應(yīng)用層協(xié)議_ HTTPS協(xié)議學(xué)習(xí)及原理理解

    「網(wǎng)絡(luò)編程」應(yīng)用層協(xié)議_ HTTPS協(xié)議學(xué)習(xí)及原理理解

    「前言」文章內(nèi)容大致是應(yīng)用層協(xié)議的HTTPS協(xié)議講解,續(xù)上篇HTTP協(xié)議。 「歸屬專欄」網(wǎng)絡(luò)編程 「主頁鏈接」個(gè)人主頁 「筆者」楓葉先生(fy) HTTPS(HyperText Transfer Protocol Secure) 是一種通過加密和身份驗(yàn)證保護(hù)網(wǎng)絡(luò)通信安全的協(xié)議。它是基于HTTP協(xié)議的安全版本,也是工作在應(yīng)用

    2024年02月16日
    瀏覽(24)
  • 網(wǎng)絡(luò)編程:TCP粘包問題——各層粘包/拆包、Nagle 算法、Go實(shí)現(xiàn)長度字段協(xié)議解決TCP粘包、使用TCP的應(yīng)用層協(xié)議設(shè)計(jì)

    網(wǎng)絡(luò)編程:TCP粘包問題——各層粘包/拆包、Nagle 算法、Go實(shí)現(xiàn)長度字段協(xié)議解決TCP粘包、使用TCP的應(yīng)用層協(xié)議設(shè)計(jì)

    1.1 TCP介紹 如上圖,TCP具有面向連接、可靠、基于字節(jié)流三大特點(diǎn)。 字節(jié)流可以理解為一個(gè)雙向的通道里流淌的數(shù)據(jù),這個(gè)數(shù)據(jù)其實(shí)就是我們常說的二進(jìn)制數(shù)據(jù),簡單來說就是一大堆 01 串。純裸TCP收發(fā)的這些 01 串之間是沒有任何邊界的,你根本不知道到哪個(gè)地方才算一條完

    2024年02月04日
    瀏覽(24)
  • Linux系統(tǒng)應(yīng)用編程(五)Linux網(wǎng)絡(luò)編程(上篇)

    Linux系統(tǒng)應(yīng)用編程(五)Linux網(wǎng)絡(luò)編程(上篇)

    1.兩個(gè)網(wǎng)絡(luò)模型和常見協(xié)議 (1)OSI七層模型(物數(shù)網(wǎng)傳會(huì)表應(yīng)) 物理層、數(shù)據(jù)鏈路層、網(wǎng)絡(luò)層、傳輸層、會(huì)話層、表示層、應(yīng)用層(自下到上) (2)TCP/IP四層模型(網(wǎng)網(wǎng)傳應(yīng)) 網(wǎng)絡(luò)接口層(鏈路層)、網(wǎng)絡(luò)層、傳輸層、應(yīng)用層 (3)常見網(wǎng)絡(luò)協(xié)議所屬層 2.字節(jié)序 (1)兩種

    2023年04月25日
    瀏覽(22)
  • C++中的網(wǎng)絡(luò)編程和安全性:實(shí)現(xiàn)安全的Web應(yīng)用程序和網(wǎng)絡(luò)應(yīng)用程序

    作者:禪與計(jì)算機(jī)程序設(shè)計(jì)藝術(shù) 《67. C++中的網(wǎng)絡(luò)編程和安全性:實(shí)現(xiàn)安全的Web應(yīng)用程序和網(wǎng)絡(luò)應(yīng)用程序》 1.1. 背景介紹 隨著互聯(lián)網(wǎng)的快速發(fā)展,網(wǎng)絡(luò)應(yīng)用程序在人們的生活和工作中扮演著越來越重要的角色,網(wǎng)絡(luò)編程和安全性也成為了現(xiàn)代應(yīng)用程序的重要組成部分。在網(wǎng)絡(luò)

    2024年02月16日
    瀏覽(25)
  • 初學(xué)記錄【linux應(yīng)用】 TCP/UDP 網(wǎng)絡(luò)編程 C語言

    初學(xué)記錄【linux應(yīng)用】 TCP/UDP 網(wǎng)絡(luò)編程 C語言

    以下內(nèi)容分別為TCP 與 UDP編程,內(nèi)容有相似或者重合部分,可根據(jù)流程 相互對(duì)照學(xué)習(xí),都已經(jīng)附上源碼 。 **1.** socket 創(chuàng)建 tcp套接字 (監(jiān)聽的套接字) 2、IPv4套接字地址結(jié)構(gòu) #include netinet/in.h struct in_addr: 如果使用 Internet 所以 sin_family 一般為 AF_INET。 ? sin_addr 設(shè)置為 INADDR_AN

    2024年02月03日
    瀏覽(27)
  • 《3.linux應(yīng)用編程和網(wǎng)絡(luò)編程-第8部分-3.8.網(wǎng)絡(luò)基礎(chǔ)》 3.8.1.網(wǎng)絡(luò)通信概述 3.8.3.網(wǎng)絡(luò)通信基礎(chǔ)知識(shí)2

    《3.linux應(yīng)用編程和網(wǎng)絡(luò)編程-第8部分-3.8.網(wǎng)絡(luò)基礎(chǔ)》 3.8.1.網(wǎng)絡(luò)通信概述 3.8.3.網(wǎng)絡(luò)通信基礎(chǔ)知識(shí)2

    ????進(jìn)程間通信: 管道 、 信號(hào)量、 共享內(nèi)存, 技術(shù)多,操作麻煩 ? ??線程就是解決 進(jìn)程間 通信 麻煩的事情,這是線程的 優(yōu)勢(shì) 3.8.1.網(wǎng)絡(luò)通信概述 3.8.1.1、從進(jìn)程間通信說起: 網(wǎng)絡(luò)域套接字socket , 網(wǎng)絡(luò)通信其實(shí)就是位于網(wǎng)絡(luò)中不同主機(jī)上面? ? ? ? ? ? ? ? ? ?的?

    2024年02月15日
    瀏覽(27)
  • 了解ET模式和LT模式:Linux網(wǎng)絡(luò)編程中的事件觸發(fā)方式

    當(dāng)談到Linux網(wǎng)絡(luò)編程中的ET(邊緣觸發(fā))模式和LT(水平觸發(fā))模式時(shí),我們需要理解它們?cè)谑录?qū)動(dòng)編程中的作用和區(qū)別。下面是一篇詳細(xì)解釋這兩種模式的博文,包含代碼示例。 摘要: 在Linux網(wǎng)絡(luò)編程中,ET(邊緣觸發(fā))模式和LT(水平觸發(fā))模式是兩種常用的事件觸發(fā)方式

    2024年02月11日
    瀏覽(14)
  • 網(wǎng)絡(luò)編程套接字應(yīng)用分享【Linux &C/C++ 】【UDP應(yīng)用 | TCP應(yīng)用 | TCP&線程池小項(xiàng)目】

    網(wǎng)絡(luò)編程套接字應(yīng)用分享【Linux &C/C++ 】【UDP應(yīng)用 | TCP應(yīng)用 | TCP&線程池小項(xiàng)目】

    目錄 前提知識(shí) 1. 理解源ip,目的ip和Macip 2. 端口號(hào) 3. 初識(shí)TCP,UDP協(xié)議 4.?網(wǎng)絡(luò)字節(jié)序 5. socket 編程 sockaddr類型? 一,基于udp協(xié)議編程? 1. socket——?jiǎng)?chuàng)建套接字 2. bind——將套接字強(qiáng)綁定? 3. recvfrom——接受數(shù)據(jù) 4. sendto——發(fā)出信息 ?遇到的問題 (1. 云服務(wù)器中以及無法分配I

    2024年04月08日
    瀏覽(28)
  • [linux--->應(yīng)用層網(wǎng)絡(luò)通信協(xié)議]

    [linux--->應(yīng)用層網(wǎng)絡(luò)通信協(xié)議]

    協(xié)議本質(zhì)是收發(fā)端雙方約定好格式的數(shù)據(jù),常見協(xié)議是用結(jié)構(gòu)體或者類的方式來表達(dá),結(jié)構(gòu)化的數(shù)據(jù)是為了方便被應(yīng)用層解讀,這個(gè)結(jié)構(gòu)體中可能包括發(fā)送者ip和端口號(hào)以及主機(jī)名,還有通信信息,應(yīng)用層可以用結(jié)構(gòu)體區(qū)分并使用信息;使用結(jié)構(gòu)體直接傳遞,但是可能會(huì)因?yàn)橄到y(tǒng)的不同

    2024年02月15日
    瀏覽(16)
  • Linux網(wǎng)絡(luò):應(yīng)用層之HTTP協(xié)議

    Linux網(wǎng)絡(luò):應(yīng)用層之HTTP協(xié)議

    我們程序員寫的一個(gè)個(gè)解決實(shí)際問題,滿足日常需求的網(wǎng)絡(luò)程序,都是在應(yīng)用層。 協(xié)議是一種約定。網(wǎng)絡(luò)協(xié)議是計(jì)算機(jī)網(wǎng)絡(luò)中通信雙方都必須遵守的一組約定。 在網(wǎng)絡(luò)通信中,都是以 “字符串” 的方式來發(fā)送和接收數(shù)據(jù)的。 如果要發(fā)送和接收一些結(jié)構(gòu)化的數(shù)據(jù),就需要序

    2023年04月26日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包