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

select實(shí)現(xiàn)服務(wù)器并發(fā)

這篇具有很好參考價(jià)值的文章主要介紹了select實(shí)現(xiàn)服務(wù)器并發(fā)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

select的TCP服務(wù)器代碼

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <sys/time.h>

#define ERR_MSG(msg)  do{\
    fprintf(stderr, "__%d__:", __LINE__); \
    perror(msg);\
}while(0)

#define PORT 8888               //端口號(hào),范圍1024~49151
#define IP  "192.168.43.233"   //本機(jī)IP,ifconfig


int keybord_events(fd_set readfds);
int cliConnect_events(int, struct sockaddr_in*, fd_set *, int *);
int cliRcvSnd_events(int, struct sockaddr_in*, fd_set *, int* );

int main(int argc, const char *argv[])
{
    //創(chuàng)建流式套接字 socket
    int sfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sfd < 0)
    {
        ERR_MSG("socket");
        return -1;
    }
    printf("socket create success sfd=%d\n", sfd);

    //允許端口快速的被復(fù)用
    int reuse = 1;
    if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
    {
        ERR_MSG("setsockopt");
        return -1;
    }
    printf("允許端口快速的被復(fù)用成功\n");


    //填充地址信息結(jié)構(gòu)體給bind函數(shù)綁定,
    //真實(shí)的地址信息結(jié)構(gòu)體根據(jù)地址族指定 AF_INET:man 7 ip
    struct sockaddr_in sin;
    sin.sin_family      = AF_INET;      //必須填A(yù)F_INET;
    sin.sin_port        = htons(PORT);  //端口號(hào)的網(wǎng)絡(luò)字節(jié)序
    sin.sin_addr.s_addr = inet_addr(IP);//本機(jī)IP


    //綁定服務(wù)器的地址信息---> 必須綁定 bind
    if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
    {
        ERR_MSG("bind");
        return -1;
    }
    printf("bind success\n");


    //將套接字設(shè)置為被動(dòng)監(jiān)聽狀態(tài) listen
    if(listen(sfd, 128) < 0)
    {
        ERR_MSG("listen");
        return -1;
    }
    printf("listen success\n");

    //創(chuàng)建一個(gè)讀集合
    fd_set readfds, tempfds;

    //fd_set 本質(zhì)上是一個(gè)結(jié)構(gòu)體,結(jié)構(gòu)體中有一個(gè)整形數(shù)組。
    //若不清空,則會(huì)存有隨機(jī)值,可能會(huì)隨機(jī)到有效的,但是不需要監(jiān)測(cè)的文件描述符
    //清空集合
    FD_ZERO(&readfds);

    //將需要監(jiān)測(cè)的文件描述符添加到集合中
    FD_SET(0, &readfds);
    FD_SET(sfd, &readfds);

    int maxfd = sfd;                    //存儲(chǔ)最大的文件描述符

    int s_res = -1;
    ssize_t res = -1;
    char buf[128] = "";
    struct sockaddr_in saveCin[1024];   //備份連接成功的客戶端的地址信息,用下標(biāo)來(lái)對(duì)應(yīng)文件描述符


    while(1)
    {
        tempfds = readfds;
        //執(zhí)行IO多路復(fù)用函數(shù)
        s_res = select(maxfd+1, &tempfds, NULL, NULL, NULL);
        if(s_res < 0)
        {
            ERR_MSG("select");
            return -1;
        }
        else if(0 == s_res)
        {
            printf("time out,,\n");
            break;
        }

        printf("__%d__\n", __LINE__);
        //能運(yùn)行到當(dāng)前位置,則代表select函數(shù)解除阻塞,即代表集合中有文件描述符準(zhǔn)備就緒
        //此時(shí)集合中會(huì)只剩下產(chǎn)生事件的文件描述符,例如:
        //0號(hào)準(zhǔn)備就緒,則集合中會(huì)只剩下0號(hào)
        //sfd準(zhǔn)備就緒,則集合中會(huì)只剩下sfd
        //0和sfd均準(zhǔn)備就緒,則集合中會(huì)剩下0和sfd;
        //只需要判斷集合中剩下哪個(gè)文件描述符,走對(duì)應(yīng)處理函數(shù)即可;

        for(int i=0; i<=maxfd; i++)
        {
            if(FD_ISSET(i, &tempfds) == 0)
                continue;

            //能運(yùn)行到當(dāng)前位置,則說(shuō)明i所代表的文件描述符在集合中
            if(0 == i)          //0在集合中
            {
                printf("觸發(fā)鍵盤輸入事件\n");
                keybord_events(readfds);
            }
            else if(sfd == i)       //sfd在集合中
            {
                printf("觸發(fā)客戶端連接事件\n");
                cliConnect_events(sfd, saveCin, &readfds, &maxfd);
            }
            else
            {
                printf("觸發(fā)客戶端交互事件\n");
                cliRcvSnd_events(i, saveCin, &readfds, &maxfd);
            }
        }

    }


    if(close(sfd) < 0)
    {
        ERR_MSG("close");
        return -1;
    }

    return 0;
}

//鍵盤輸入事件
int keybord_events(fd_set readfds)
{
    char buf[128] = "";
    int sndfd = -1;             //從終端獲取一個(gè)文件描述符,發(fā)送數(shù)據(jù)給該文件描述符對(duì)應(yīng)的客戶端
    bzero(buf, sizeof(buf));

    int res = scanf("%d %s", &sndfd, buf);
    while(getchar() != 10);
    if(res != 2)                //終端輸入的數(shù)據(jù)格式錯(cuò)誤
    {
        printf("輸入數(shù)據(jù)的格式錯(cuò)誤,:fd string\n");
        return -1;                                                                                                          
    }

    if(sndfd<=2 || FD_ISSET(sndfd, &readfds)==0)        //判斷文件描述符的合法性
    {
        printf("非法的文件描述符:sndfd=%d\n", sndfd);
        return -1;
    }

    if(send(sndfd, buf, sizeof(buf), 0) < 0)
    {
        ERR_MSG("send");
        return -1;
    }
    printf("send success\n");


    return 0;
}

//客戶端連接事件
int cliConnect_events(int sfd, struct sockaddr_in saveCin[], fd_set *preadfds, int *pmaxfd)
{
    int newfd = -1;
    struct sockaddr_in cin;             //存儲(chǔ)客戶端的地址信息
    socklen_t addrlen = sizeof(cin);    //真實(shí)的地址信息結(jié)構(gòu)體的大小

    newfd = accept(sfd, (struct sockaddr*)&cin, &addrlen);
    if(newfd < 0)
    {
        ERR_MSG("newfd");
        return -1;
    }
    printf("[%s:%d]客戶端連接成功 newfd=%d\n", \
            inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd);
    saveCin[newfd] = cin;                       //將cin另存到newfd對(duì)應(yīng)的下標(biāo)位置去

    FD_SET(newfd, preadfds);                    //將newfd添加到集合中
    *pmaxfd = *pmaxfd>newfd ? *pmaxfd:newfd;    //更新maxfd

    return 0;
}

//客戶端交互事件
int cliRcvSnd_events(int fd, struct sockaddr_in* saveCin, fd_set *preadfds, int* pmaxfd)
{
    char buf[128] = "";
    //清空字符串
    bzero(buf, sizeof(buf));    //memset

    //接收
    ssize_t res = recv(fd, buf, sizeof(buf), 0);
    if(res < 0)
    {
        ERR_MSG("recv");
        return -1;
    }
    else if(0 == res)
    {
        printf("[%s:%d]客戶端下線 newfd=%d\n", \
                inet_ntoa(saveCin[fd].sin_addr), ntohs(saveCin[fd].sin_port), fd);

        close(fd);              //關(guān)閉文件描述符
        FD_CLR(fd, preadfds);   //將文件描述符從集合中剔除

        //由于剔除的文件描述符可能是最大文件描述符,所以要更新maxfd 
        //從大往小判斷,若在集合中,則該文件描述符就是最大的文件描述符
        /*
           for(; *pmaxfd>=0; *pmaxfd--)
           {
           if(FD_ISSET(*pmaxfd, preadfds))
           break;
           }
           */

        while(FD_ISSET(*pmaxfd, preadfds)==0 && (*pmaxfd)-->=0);
        return 0;

    }
    printf("[%s:%d] newfd=%d : %s\n", \
            inet_ntoa(saveCin[fd].sin_addr), ntohs(saveCin[fd].sin_port), fd, buf);

    //發(fā)送
    strcat(buf, "*_*");
    if(send(fd, buf, sizeof(buf), 0) < 0)
    {
        ERR_MSG("send");
        return -1;
    }
    printf("send success\n");

    return 0;
}

select實(shí)現(xiàn)服務(wù)器并發(fā),服務(wù)器,php,網(wǎng)絡(luò)?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-729735.html

到了這里,關(guān)于select實(shí)現(xiàn)服務(wù)器并發(fā)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(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)文章

  • 【TCP/IP】利用I/O復(fù)用技術(shù)實(shí)現(xiàn)并發(fā)服務(wù)器 - select函數(shù)

    【TCP/IP】利用I/O復(fù)用技術(shù)實(shí)現(xiàn)并發(fā)服務(wù)器 - select函數(shù)

    目錄 I/O復(fù)用技術(shù) select函數(shù) 設(shè)置文件描述符 指定監(jiān)視范圍 設(shè)置超時(shí) I/O復(fù)用服務(wù)器端的實(shí)現(xiàn) ?????? 由服務(wù)器創(chuàng)建多個(gè)進(jìn)程來(lái)實(shí)現(xiàn)并發(fā)的做法有時(shí)會(huì)帶來(lái)一些問題,比如:內(nèi)存上的開銷、CPU的大量占用等,這些因素會(huì)消耗掉服務(wù)器端有限的計(jì)算資源、進(jìn)而影響程序之間的執(zhí)

    2024年02月08日
    瀏覽(21)
  • 計(jì)算機(jī)網(wǎng)絡(luò)編程 | 并發(fā)服務(wù)器代碼實(shí)現(xiàn)(多進(jìn)程/多線程)

    計(jì)算機(jī)網(wǎng)絡(luò)編程 | 并發(fā)服務(wù)器代碼實(shí)現(xiàn)(多進(jìn)程/多線程)

    歡迎關(guān)注博主 Mindtechnist 或加入【Linux C/C++/Python社區(qū)】一起學(xué)習(xí)和分享Linux、C、C++、Python、Matlab,機(jī)器人運(yùn)動(dòng)控制、多機(jī)器人協(xié)作,智能優(yōu)化算法,濾波估計(jì)、多傳感器信息融合,機(jī)器學(xué)習(xí),人工智能等相關(guān)領(lǐng)域的知識(shí)和技術(shù)。 專欄:《網(wǎng)絡(luò)編程》 當(dāng)涉及到構(gòu)建高性能的服務(wù)

    2024年02月08日
    瀏覽(36)
  • libevent高并發(fā)網(wǎng)絡(luò)編程 - 04_libevent實(shí)現(xiàn)http服務(wù)器

    libevent高并發(fā)網(wǎng)絡(luò)編程 - 04_libevent實(shí)現(xiàn)http服務(wù)器

    鏈接: C/C++Linux服務(wù)器開發(fā)/后臺(tái)架構(gòu)師【零聲教育】-學(xué)習(xí)視頻教程-騰訊課堂 在libevent中,HTTP的實(shí)現(xiàn)主要是通過(guò) evhttp 模塊來(lái)完成的。 evhttp 提供了一個(gè)高層次的HTTP服務(wù)器接口,可以處理HTTP請(qǐng)求并發(fā)送HTTP響應(yīng)。 在源碼中,libevent的HTTP協(xié)議處理主要是通過(guò) evhttp 模塊來(lái)完成的。

    2024年02月15日
    瀏覽(29)
  • 多進(jìn)程并發(fā)TCP服務(wù)器模型(含客戶端)(網(wǎng)絡(luò)編程 C語(yǔ)言實(shí)現(xiàn))

    摘要 :大家都知道不同pc間的通信需要用到套接字sockte來(lái)實(shí)現(xiàn),但是服務(wù)器一次只能收到一個(gè)客戶端發(fā)來(lái)的消息,所以為了能讓服務(wù)器可以接收多個(gè)客戶端的連接與消息的傳遞,我們就引入了多進(jìn)程并發(fā)這樣一個(gè)概念。聽名字就可以知道--需要用到進(jìn)程,當(dāng)然也有多線程并發(fā)

    2024年02月17日
    瀏覽(105)
  • TCP服務(wù)器的演變過(guò)程:使用epoll構(gòu)建reactor網(wǎng)絡(luò)模型實(shí)現(xiàn)百萬(wàn)級(jí)并發(fā)(詳細(xì)代碼)

    TCP服務(wù)器的演變過(guò)程:使用epoll構(gòu)建reactor網(wǎng)絡(luò)模型實(shí)現(xiàn)百萬(wàn)級(jí)并發(fā)(詳細(xì)代碼)

    手把手教你從0開始編寫TCP服務(wù)器程序,體驗(yàn)開局一塊磚,大廈全靠壘。 為了避免篇幅過(guò)長(zhǎng)使讀者感到乏味,對(duì)【TCP服務(wù)器的開發(fā)】進(jìn)行分階段實(shí)現(xiàn),一步步進(jìn)行優(yōu)化升級(jí)。 本節(jié),在上一章節(jié)介紹了如何使用epoll開發(fā)高效的服務(wù)器,本節(jié)將介紹使用epoll構(gòu)建reactor網(wǎng)絡(luò)模型,實(shí)

    2024年02月01日
    瀏覽(30)
  • Python向帶有SSL/TSL認(rèn)證服務(wù)器發(fā)送網(wǎng)絡(luò)請(qǐng)求小實(shí)踐(附并發(fā)http請(qǐng)求實(shí)現(xiàn)asyncio+aiohttp)

    Python向帶有SSL/TSL認(rèn)證服務(wù)器發(fā)送網(wǎng)絡(luò)請(qǐng)求小實(shí)踐(附并發(fā)http請(qǐng)求實(shí)現(xiàn)asyncio+aiohttp)

    最近工作中遇到這樣的一個(gè)場(chǎng)景:給客戶發(fā)送文件的時(shí)候,為保證整個(gè)過(guò)程中,文件不會(huì)被篡改,需要在發(fā)送文件之間, 對(duì)發(fā)送的文件進(jìn)行簽名, 而整個(gè)簽名系統(tǒng)是另外一個(gè)團(tuán)隊(duì)做的, 提供了一個(gè)接口服務(wù)完成簽名,但訪問這個(gè)接口需要提供他們團(tuán)隊(duì)提供的證書鏈先進(jìn)行認(rèn)

    2024年04月16日
    瀏覽(27)
  • 常見網(wǎng)絡(luò)服務(wù)器并發(fā)模型

    常見網(wǎng)絡(luò)服務(wù)器并發(fā)模型

    近些年,隨著互聯(lián)網(wǎng)的大發(fā)展,高并發(fā)服務(wù)器技術(shù)也快速進(jìn)步,從簡(jiǎn)單的循環(huán)服務(wù)器模型處理少量網(wǎng)絡(luò)并發(fā)請(qǐng)求,演進(jìn)到解決C10K,C10M問題的高并發(fā)服務(wù)器模型。本文主要以TCP為例,總結(jié)了幾種常見的網(wǎng)絡(luò)服務(wù)器模型的實(shí)現(xiàn)方式,優(yōu)缺點(diǎn),以及應(yīng)用實(shí)例。 單線程循環(huán) 單線程循

    2024年02月08日
    瀏覽(32)
  • 【網(wǎng)絡(luò)編程】高性能并發(fā)服務(wù)器源碼剖析

    【網(wǎng)絡(luò)編程】高性能并發(fā)服務(wù)器源碼剖析

    ? hello !大家好呀! 歡迎大家來(lái)到我的網(wǎng)絡(luò)編程系列之洪水網(wǎng)絡(luò)攻擊,在這篇文章中, 你將會(huì)學(xué)習(xí)到在網(wǎng)絡(luò)編程中如何搭建一個(gè)高性能的并發(fā)服務(wù)器,并且我會(huì)給出源碼進(jìn)行剖析,以及手繪UML圖來(lái)幫助大家來(lái)理解,希望能讓大家更能了解網(wǎng)絡(luò)編程技術(shù)?。。?希望這篇文章能

    2024年04月15日
    瀏覽(43)
  • linux并發(fā)服務(wù)器 —— linux網(wǎng)絡(luò)編程(七)

    linux并發(fā)服務(wù)器 —— linux網(wǎng)絡(luò)編程(七)

    C/S結(jié)構(gòu) - 客戶機(jī)/服務(wù)器;采用兩層結(jié)構(gòu),服務(wù)器負(fù)責(zé)數(shù)據(jù)的管理,客戶機(jī)負(fù)責(zé)完成與用戶的交互;C/S結(jié)構(gòu)中,服務(wù)器 - 后臺(tái)服務(wù),客戶機(jī) - 前臺(tái)功能; 優(yōu)點(diǎn) 1. 充分發(fā)揮客戶端PC處理能力,先在客戶端處理再提交服務(wù)器,響應(yīng)速度快; 2. 操作界面好看,滿足個(gè)性化需求; 3.

    2024年02月09日
    瀏覽(23)
  • 【高并發(fā)網(wǎng)絡(luò)通信架構(gòu)】引入IO多路復(fù)用(select,poll,epoll)實(shí)現(xiàn)高并發(fā)tcp服務(wù)端

    【高并發(fā)網(wǎng)絡(luò)通信架構(gòu)】引入IO多路復(fù)用(select,poll,epoll)實(shí)現(xiàn)高并發(fā)tcp服務(wù)端

    目錄 一,往期文章 二,基本概念 IO多路復(fù)用 select 模型 poll 模型 epoll 模型 select,poll,epoll 三者對(duì)比 三,函數(shù)清單 1.select 方法 2.fd_set 結(jié)構(gòu)體 3.poll 方法 4.struct pollfd 結(jié)構(gòu)體 5.epoll_create 方法 6.epoll_ctl 方法 7.epoll_wait 方法 8.struct epoll_event 結(jié)構(gòu)體 四,代碼實(shí)現(xiàn) select 操作流程 s

    2024年02月12日
    瀏覽(33)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包