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

TCP服務(wù)器實現(xiàn)—多進(jìn)程版,多線程版,線程池版

這篇具有很好參考價值的文章主要介紹了TCP服務(wù)器實現(xiàn)—多進(jìn)程版,多線程版,線程池版。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

目錄

前言

1.存在的問題

2.多進(jìn)程版

3.多線程版

4.線程池版

總結(jié)


前言

? ? ? ? 在上一篇文章中使用TCP協(xié)議實現(xiàn)了一個簡單的服務(wù)器,可以用來服務(wù)端和客戶端通信,但是之前的服務(wù)器存在一個問題,就是當(dāng)有多個客戶端連接服務(wù)器的時候,服務(wù)器只能和一個客戶端通信,其它的客戶端是無法通信的,這是為什么呢?有該如何解決呢?將在這篇文章中為大家介紹

1.存在的問題

如圖所示:

TCP服務(wù)器實現(xiàn)—多進(jìn)程版,多線程版,線程池版,服務(wù)器,tcp/ip,運維

?為什么會存在這樣的問題呢?

TCP服務(wù)器實現(xiàn)—多進(jìn)程版,多線程版,線程池版,服務(wù)器,tcp/ip,運維

如上圖所示,之前我們實現(xiàn)的服務(wù)器是單進(jìn)程版的,所以當(dāng)?shù)谝淮魏涂蛻舳私⑦B接完成之后,就死循環(huán)處理讀取信息的邏輯了,所以就無法再和新的客戶端建立連接了 。找到問題之后,很明顯解決方式就是將建立連接和通信分開執(zhí)行,此時我們就可以使用多進(jìn)程和多線程來解決了,下面我們就具體來實現(xiàn)以下如何使用多進(jìn)程和多線程。

2.多進(jìn)程版

實現(xiàn)思路:與客戶端建立連接完成,fork創(chuàng)建子進(jìn)程,讓父進(jìn)程繼續(xù)建立連接,讓子進(jìn)程實現(xiàn)后續(xù)的數(shù)據(jù)通信。

這樣實現(xiàn)存在的問題:當(dāng)父進(jìn)程創(chuàng)建完子進(jìn)程之后,需要使用waitpid回收子進(jìn)程的資源,否則子進(jìn)程就會變?yōu)榻┦M(jìn)程,導(dǎo)致資源泄漏,但是使用waitpid回收子進(jìn)程資源,程序變?yōu)榇谢瘓?zhí)行了,就無法實現(xiàn)之前的需求,讓父進(jìn)程負(fù)責(zé)建立連接,子進(jìn)程負(fù)責(zé)數(shù)據(jù)通信了。

解決方式有兩種:

1.fork創(chuàng)建子進(jìn)程,在子進(jìn)程內(nèi)部再fork創(chuàng)建子進(jìn)程,然后讓父進(jìn)程直接退出,此時之前的子進(jìn)程作為父進(jìn)程退出,新創(chuàng)建的子進(jìn)程就變?yōu)楣聝哼M(jìn)程被操作系統(tǒng)領(lǐng)養(yǎng),并不會造成資源泄漏,并且讓該子進(jìn)程負(fù)責(zé)通信

2.因為子進(jìn)程退出之后操作系統(tǒng)會發(fā)送一個SIGCHLD信號,所以可以使用signal函數(shù)捕捉SIGCHLD信號,將默認(rèn)處理動作設(shè)置為SIG_IGN,在這個默認(rèn)動作里會回收子進(jìn)程的資源,并不會造成資源泄漏,并且讓該子進(jìn)程負(fù)責(zé)通信

思路1代碼:

pid_t id = fork();
if(id == 0)//child
{
    close(_sock);
    if(fork() > 0)
        exit(0);
    serviceIO(sock);
    close(sock);
    exit(0);
}
close(sock);
waitpid(id,nullptr,0);

思路2代碼:

signal(SIGCHLD,SIG_IGN);
if(id == 0)//child
{
    // 子進(jìn)程會繼承父進(jìn)程的文件描述符表,當(dāng)子進(jìn)程不需要時進(jìn)行關(guān)閉,
    // 防止子進(jìn)程文件描述符資源泄露
    close(_sock);
    serviceIO(sock);
    close(sock);
    exit(0);
}

運行截圖:

[myl@VM-8-12-centos tcp]$ ./tcpServer 8080
create socket success
bind socket success
listen socket success
accept a new link success
sock: 4
accept a new link success
sock: 4
recvice message: 你好,我是客戶端1
recvice message: 你好,我是客戶端2

此時就實現(xiàn)了一個客戶端可以被多個服務(wù)端連接并且實現(xiàn)通信。

3.多線程版

說明:相比于多進(jìn)程,多線程的創(chuàng)建和銷毀對操作系統(tǒng)是更輕量的,消耗的資源也是更少的,所以實現(xiàn)數(shù)據(jù)通信可以采用多線程的方式,讓主線程負(fù)責(zé)建立,讓從線程負(fù)責(zé)數(shù)據(jù)通信

代碼實現(xiàn):

class TcpServerData
{
public:
    TcpServerData(TcpServer* self,int sock)
    :_self(self),_sock(sock) {}
public:
    TcpServer* _self;
    int _sock;
};
cout << "我是主線程" << endl;
pthread_t tid;
TcpServerData* tsd = new TcpServerData(this,sock);
pthread_create(&tid,nullptr,start_routine,tsd);

//因為是類內(nèi)成員函數(shù),必須包含this指針,但是start_routine作為參數(shù)是沒有this指針的
//所以start_routine函數(shù)必須加上static,靜態(tài)成員方法是不能訪問類內(nèi)成員的,所以參數(shù)傳遞this
//調(diào)用serviceIO,但是serviceIO函數(shù)需要傳遞參數(shù)sock,所以可以封裝一個結(jié)構(gòu)體,在結(jié)構(gòu)體中包含成員
//屬性sock和this
static void* start_routine(void* args) {
//設(shè)置與主線程分離,此時主線程不需要等待從線程退出了,而是繼續(xù)建立連接
cout << "我是從線程" << endl;
pthread_detach(pthread_self());
TcpServerData* t = static_cast<TcpServerData*>(args);
t->_self->serviceIO(t->_sock);
close(t->_sock);
delete t;
return nullptr;

運行截圖:

[myl@VM-8-12-centos tcp]$ ./tcpServer 8080
create socket success
bind socket success
listen socket success
accept a new link success
sock: 4
我是主線程
我是從線程
recvice message: 你好,我是客戶端1
accept a new link success
sock: 5
我是主線程
我是從線程
recvice message: 你好,我是客戶端2

4.線程池版

說明:線程池版的實現(xiàn)思路是基于多線程,雖然多線程創(chuàng)建和銷毀的消耗比多進(jìn)程的低,但是為了更進(jìn)一步提升效率,可以預(yù)先創(chuàng)建好一批線程,主線程負(fù)責(zé)建立連接獲取任務(wù),然后將任務(wù)加入到隊列中,讓預(yù)先創(chuàng)建好的線程從隊列中獲取任務(wù),然后處理獲取到的任務(wù)。

代碼實現(xiàn):

void start()
{
    //線程池初始化:預(yù)先創(chuàng)建好一批線程:
    ThreadPool<Task>::getInstance()->run();
    for (;;)
    {
        // 建立連接:
        struct sockaddr_in peer;
        socklen_t len = sizeof(peer);
        int sock = accept(_sock, (struct sockaddr *)&peer, &len); 
        if (sock < 0)
        {
            logMessage(ERROR, "accept error, next");
            continue;
        }
        logMessage(NORMAL, "accept a new link success");
        std::cout << "sock: " << sock << std::endl;
        //未來通信全部用sock,面向字節(jié)流的,后續(xù)全部都是文件操作:
        ThreadPool<Task>::getInstance()->push(Task(sock,serviceIO));
    }
}

運行截圖:

[myl@VM-8-12-centos tcp]$ ./tcpServer 8080
create socket success
bind socket success
listen socket success
thread-1 start ...
thread-2 start ...
thread-3 start ...
thread-4 start ...
thread-5 start ...
thread-6 start ...
thread-7 start ...
thread-8 start ...
thread-9 start ...
thread-10 start ...
accept a new link success
sock: 4
accept a new link success
sock: 5
recv message: 你好,我是客戶端1
recv message: 你好,我是客戶端2
注:關(guān)于線程池詳細(xì)的設(shè)計與實現(xiàn)可以觀看線程池這篇文章,里面有相信的代碼實現(xiàn)

總結(jié)

? ? ? ? 以上就是關(guān)于TCP服務(wù)器實現(xiàn)多進(jìn)程版,多線程版,線程池版的詳細(xì)介紹,可以通過這篇文章發(fā)現(xiàn)之前在系統(tǒng)中學(xué)習(xí)的知識在網(wǎng)絡(luò)中全部結(jié)合起來了,今天的介紹就到這里了,感謝大家的閱讀,我們下次再見!文章來源地址http://www.zghlxwxcb.cn/news/detail-659748.html

到了這里,關(guān)于TCP服務(wù)器實現(xiàn)—多進(jìn)程版,多線程版,線程池版的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • TCP服務(wù)器的演變過程:多進(jìn)程實現(xiàn)一對多的TCP服務(wù)器

    TCP服務(wù)器的演變過程:多進(jìn)程實現(xiàn)一對多的TCP服務(wù)器

    手把手教你從0開始編寫TCP服務(wù)器程序,體驗開局一塊磚,大廈全靠壘。 為了避免篇幅過長使讀者感到乏味,對【TCP服務(wù)器的開發(fā)】進(jìn)行分階段實現(xiàn),一步步進(jìn)行優(yōu)化升級。本節(jié)在上一章節(jié)的基礎(chǔ)上,改為多進(jìn)程方式實現(xiàn)TCP服務(wù)器,為每個新接入的客戶端分配進(jìn)程,實現(xiàn)一個

    2024年02月04日
    瀏覽(21)
  • 【TCP/IP】多進(jìn)程服務(wù)器的實現(xiàn)(進(jìn)階) - 多進(jìn)程服務(wù)器模型及代碼實現(xiàn)

    【TCP/IP】多進(jìn)程服務(wù)器的實現(xiàn)(進(jìn)階) - 多進(jìn)程服務(wù)器模型及代碼實現(xiàn)

    ???????? 經(jīng)過前面的鋪墊,我們已經(jīng)具備實現(xiàn)并發(fā)服務(wù)器的基礎(chǔ)了,接下來讓我們嘗試將之前的單任務(wù)回聲服務(wù)器改裝成多任務(wù)并發(fā)模式吧! ????????在編寫代碼前,先讓我們大致將多任務(wù)(回聲)服務(wù)器的模型抽象一下,如下圖所示: ? ? ? ? 當(dāng)客戶端請求服務(wù)(

    2024年02月08日
    瀏覽(15)
  • TCP服務(wù)器的演變過程:揭秘使用多線程實現(xiàn)一對多的TCP服務(wù)器

    TCP服務(wù)器的演變過程:揭秘使用多線程實現(xiàn)一對多的TCP服務(wù)器

    手把手教你從0開始編寫TCP服務(wù)器程序,體驗開局一塊磚,大廈全靠壘。 為了避免篇幅過長使讀者感到乏味,對【TCP服務(wù)器的開發(fā)】進(jìn)行分階段實現(xiàn),一步步進(jìn)行優(yōu)化升級。本節(jié)在上一章節(jié)的基礎(chǔ)上,添加多線程,為每個新接入的客戶端分配線程,實現(xiàn)一個服務(wù)器程序處理多

    2024年02月04日
    瀏覽(26)
  • 【TCP/IP】多進(jìn)程服務(wù)器的實現(xiàn)(進(jìn)階) - 僵尸進(jìn)程及wait、waitpid函數(shù)

    【TCP/IP】多進(jìn)程服務(wù)器的實現(xiàn)(進(jìn)階) - 僵尸進(jìn)程及wait、waitpid函數(shù)

    目錄 僵尸(Zombie)進(jìn)程 僵尸進(jìn)程的產(chǎn)生機制 僵尸進(jìn)程的危害 僵尸進(jìn)程的銷毀 wait函數(shù) waitpid函數(shù) ???????? 進(jìn)程管理在網(wǎng)絡(luò)編程中十分重要,如果未處理好,將會導(dǎo)致出現(xiàn)“僵尸進(jìn)程”,進(jìn)而影響服務(wù)器端對進(jìn)程的管控。 ????????第一次聽到這個名詞大家可能會有些陌生

    2024年02月09日
    瀏覽(22)
  • 【TCP/IP】多進(jìn)程服務(wù)器的實現(xiàn)(進(jìn)階) - 進(jìn)程的概念及fork函數(shù)

    【TCP/IP】多進(jìn)程服務(wù)器的實現(xiàn)(進(jìn)階) - 進(jìn)程的概念及fork函數(shù)

    目錄 進(jìn)程的概念及應(yīng)用 進(jìn)程的定義 進(jìn)程的ID fork函數(shù)(進(jìn)程創(chuàng)建函數(shù)) ????????多進(jìn)程(以及多線程)是現(xiàn)代計算機網(wǎng)絡(luò)的精髓。在之前,我們所做的諸如回聲服務(wù)器、回聲客戶端、文件收發(fā)等都是偏向基礎(chǔ)的單進(jìn)程應(yīng)用。而經(jīng)過前面的鋪墊,我們對Socket也有了一定了解

    2024年02月09日
    瀏覽(33)
  • 【Linux后端服務(wù)器開發(fā)】封裝線程池實現(xiàn)TCP多線程通信

    目錄 一、線程池模塊 Thread.h LockGuard.h ThreadPool.h 二、任務(wù)模塊模塊 Task.h 三、日志模塊 Log.h 四、守護(hù)進(jìn)程模塊 Deamon.h ?五、TCP通信模塊 Server.h Client.h server.cpp client.cpp 關(guān)于TCP通信協(xié)議的封裝,此篇博客有詳述: 【Linux后端服務(wù)器開發(fā)】TCP通信設(shè)計_命運on-9的博客-CSDN博客 線程池

    2024年02月16日
    瀏覽(25)
  • Qt實現(xiàn)簡易的多線程TCP服務(wù)器(附源碼)

    Qt實現(xiàn)簡易的多線程TCP服務(wù)器(附源碼)

    目錄 一.UI界面的設(shè)計 二.服務(wù)器的啟動 三.實現(xiàn)自定義的TcpServer類 1.在widget中聲明自定義TcpServer類的成員變量 2.在TcpServer的構(gòu)造函數(shù)中對于我們聲明的m_widget進(jìn)行初始化,m_widget我們用于后續(xù)的顯示消息等,說白了就是主界面的更新顯示等 四.實現(xiàn)自定義的TcpSocket類 1.TcpSocket.

    2024年04月17日
    瀏覽(21)
  • C/S架構(gòu)學(xué)習(xí)之多線程實現(xiàn)TCP并發(fā)服務(wù)器

    并發(fā)概念: 并發(fā)是指兩個或多個事件在 同一時間間隔 發(fā)生; 多線程實現(xiàn)TCP并發(fā)服務(wù)器的實現(xiàn)流程: 一、創(chuàng)建套接字(socket函數(shù)): 通信域選擇IPV4網(wǎng)絡(luò)協(xié)議、套接字類型選擇流式; 二、填充服務(wù)器的網(wǎng)絡(luò)信息結(jié)構(gòu)體: 1.定義網(wǎng)絡(luò)信息結(jié)構(gòu)體變量; 2.求出結(jié)構(gòu)體變量的內(nèi)存

    2024年02月06日
    瀏覽(27)
  • 【網(wǎng)絡(luò)編程】實現(xiàn)一個簡單多線程版本TCP服務(wù)器(附源碼)

    【網(wǎng)絡(luò)編程】實現(xiàn)一個簡單多線程版本TCP服務(wù)器(附源碼)

    accept 函數(shù)是在服務(wù)器端用于接受客戶端連接請求的函數(shù),它在監(jiān)聽套接字上等待客戶端的連接,并在有新的連接請求到來時創(chuàng)建一個新的套接字用于與該客戶端通信。 下面是 accept 函數(shù)的詳細(xì)介紹以及各個參數(shù)的意義: sockfd: 是服務(wù)器監(jiān)聽套接字的文件描述符,通常是使用

    2024年02月13日
    瀏覽(30)
  • 【TCP/IP】多進(jìn)程服務(wù)器的實現(xiàn)(進(jìn)階) - 信號處理及signal、sigaction函數(shù)

    【TCP/IP】多進(jìn)程服務(wù)器的實現(xiàn)(進(jìn)階) - 信號處理及signal、sigaction函數(shù)

    目錄 信號 signal函數(shù) sigaction函數(shù) 用信號來處理僵尸進(jìn)程 ???????? 在之前我們學(xué)習(xí)了如何處理“僵尸進(jìn)程”,不過可能也會有疑問:調(diào)用wait和waitpid函數(shù)時我們關(guān)注的始終是在子進(jìn)程上,那么在父進(jìn)程上如何實現(xiàn)對子進(jìn)程的管控呢?為此,我們引入一個概念——信號處理。

    2024年02月08日
    瀏覽(18)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包