亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? linux下各類tcp網絡服務器的實現源代碼.txt

?? Linux下各類TCP網絡服務器的實現源代碼
?? TXT
?? 第 1 頁 / 共 3 頁
字號:
Linux下各類TCP網絡服務器的實現源代碼

大家都知道各類網絡服務器程序的編寫步驟,并且都知道網絡服務器就兩大類:循環服務和并發服務。這里附上源代碼來個小結吧。

首先,循環網絡服務器編程實現的步驟是這樣的:

                              建立socket(這里用到socket()函數及函數setsockopt())
                                                            |
                                                            |
                                                           \|/
                              把socket和IP地址及端口綁定(這里用到bind函數)
                                                            |
                                                            |
                                                           \|/
                              開始監聽(這里用到listen()函數)
                                                            |
                                                            |
                                                           /\
                                                       /        \
                                               \     /           \
                    -----------------------  | 有連接|
                    |                           /   \             /
                    |                                 \         /
                    |                                     \ /
                    |                                       | 
                    |          接受新的連接(這里用到accept()函數)
                    |                                       |  /___________________________________________________
                    |                                       |  \                                                                                                                            |
                    |                                     \|/                                                                                                                              |
                    |         從連接里讀取數據(這里用到recv()系統函數,當然也可以是read()函數)                          |
                    |                                        |                                                                                                                                |
                    |                                       |                                                                                                                                |
                    |                                     \|/                                                                                                                             |
                    |          返回信息給連接(這里用到send()系統函數,當然也可以是write()函        數)                    |
                    |                                       |                                                                                                                                |
                    |                                       |                                                                                                                                |
                    |                                      /\                                                                                                                             |
                    |                                  /        \                                                                                                                         |
                    |                               /               \                                                                                                                      |
                    |                              | 還有數據 |-Y-------------------------------------------------------
                    |                              \               /
                    |                                 \         /
                    |                                     \ /
                    |________________|

這種服務器模型是典型循環服務,如果不加上多進程/線程技術,此種服務吞吐量有限,大家都可以看到,如果前一個連接服務數據沒有收發完畢后面的連接沒辦法處理。所以一般有多進程技術,對一個新連接啟用一個新進程去處理,而監聽socket繼續監聽。

/************關于本文檔********************************************
*filename: Linux下各類TCP網絡服務器的實現源代碼
*purpose: 記錄Linux下各類tcp服務程序源代碼
*wrote by: zhoulifa(zhoulifa@163.com) 周立發(http://zhoulifa.bokee.com)
Linux愛好者 Linux知識傳播者 SOHO族 開發者 最擅長C語言
*date time:2006-07-04 22:00:00
*Note: 任何人可以任意復制代碼并運用這些文檔,當然包括你的商業用途
* 但請遵循GPL
*Hope:希望越來越多的人貢獻自己的力量,為科學技術發展出力
*********************************************************************/

一個循環TCP服務源代碼(因為用fork進行多進程服務了,所以這種服務現實中也有用)如下:
/*----------------------源代碼開始--------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
/*********************************************************************
*filename: cycletcpserver.c
*purpose: 循環tcp服務端程序
*tidied by: zhoulifa(zhoulifa@163.com) 周立發(http://zhoulifa.bokee.com)
Linux愛好者 Linux知識傳播者 SOHO族 開發者 最擅長C語言
*date time:2006-07-04 22:00:00
*Note: 任何人可以任意復制代碼并運用這些文檔,當然包括你的商業用途
* 但請遵循GPL
*Thanks to: Google.com
*********************************************************************/
int main(int argc, char ** argv)
{
    int sockfd,new_fd; /* 監聽socket: sock_fd,數據傳輸socket: new_fd */
    struct sockaddr_in my_addr; /* 本機地址信息 */
    struct sockaddr_in their_addr; /* 客戶地址信息 */
    unsigned int sin_size, myport, lisnum;

    if(argv[1])  myport = atoi(argv[1]);
    else myport = 7838;

    if(argv[2])  lisnum = atoi(argv[2]);
    else lisnum = 2;

    if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket"); 
        exit(1); 
    }
    my_addr.sin_family=PF_INET;
    my_addr.sin_port=htons(myport);
    my_addr.sin_addr.s_addr = INADDR_ANY;
    bzero(&(my_addr.sin_zero), 0);
    if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
        perror("bind");
        exit(1);
    }

    if (listen(sockfd, lisnum) == -1) {
        perror("listen");
        exit(1);
    }
    while(1) {
        sin_size = sizeof(struct sockaddr_in);
        if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) {
            perror("accept");
            continue;
        }
        printf("server: got connection from %s\n",inet_ntoa(their_addr.sin_addr));
        if (!fork()) { /* 子進程代碼段 */
            if (send(new_fd, "Hello, world!\n", 14, 0) == -1) {
                perror("send");
                close(new_fd);
                exit(0);
            }
        }
        close(new_fd); /*父進程不再需要該socket*/
        waitpid(-1,NULL,WNOHANG);/*等待子進程結束,清除子進程所占用資源*/
    }
}
/*----------------------源代碼結束--------------------------------------------*/

 


一個測試客戶端代碼如下:
/*----------------------源代碼開始--------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#define MAXDATASIZE 100 /*每次最大數據傳輸量 */
/*********************************************************************
*filename: cycletcpclient.c
*purpose: 循環tcp客戶端程序
*tidied by: zhoulifa(zhoulifa@163.com) 周立發(http://zhoulifa.bokee.com)
Linux愛好者 Linux知識傳播者 SOHO族 開發者 最擅長C語言
*date time:2006-07-04 22:20:00
*Note: 任何人可以任意復制代碼并運用這些文檔,當然包括你的商業用途
* 但請遵循GPL
*Thanks to: Google.com
*Hope:希望越來越多的人貢獻自己的力量,為科學技術發展出力
*********************************************************************/

int main(int argc, char *argv[])
{
    int sockfd, numbytes;
    char buf[MAXDATASIZE];
    struct hostent *he;
    struct sockaddr_in their_addr;
    unsigned int myport;

    if(argv[2]) myport = atoi(argv[2]);
    else myport = 7838;

    if (argc != 3) {
        fprintf(stderr,"usage: %s hostname port\n", argv[0]); 
        exit(1);
    }
    if((he=gethostbyname(argv[1]))==NULL) {
        herror("gethostbyname");
        exit(1);
    }
    if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(1);
    }
    their_addr.sin_family=PF_INET;
    their_addr.sin_port=htons(myport);
    their_addr.sin_addr = *((struct in_addr *)he->h_addr);
    bzero(&(their_addr.sin_zero),0);
    if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) {
        perror("connect");
        exit(1);
    }
    if ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) == -1) {
        perror("recv");
        exit(1);
    }
    buf[numbytes] = 0;
    printf("Received: %s\n",buf);
    close(sockfd);
    return 0;
}
/*----------------------源代碼結束--------------------------------------------*/

 
用gcc cycletcpserver.c -o tcpserver和gcc cycletcpclient.c -o tcpclient分別編譯上述代碼后運行情況如下:
服務端運行顯示:
administrator@ubuzlf:/data/example/c$ ./tcpserver
server: got connection from 127.0.0.1
server: got connection from 127.0.0.1
server: got connection from 127.0.0.1
 
客戶端運行顯示:
administrator@ubuzlf:/data/example/c$ ./tcpclient 127.0.0.1 7838
Received: Hello, world!

administrator@ubuzlf:/data/example/c$ ./tcpclient 127.0.0.1 7838
Received: Hello, world!

administrator@ubuzlf:/data/example/c$ ./tcpclient 127.0.0.1 7838
Received: Hello, world!

 

不得不說的一個概念性問題:阻塞與非阻塞
在阻塞服務中,當服務器運行到accept語句而沒有客戶連接服務請求到來,那么會發生什么情況?這時服務器就會停止在accept語句上等待連接服務請求的到來;同樣,當程序運行到接收數據語句recv時,如果沒有數據可以讀取,則程序同樣會停止在接收語句上。這種情況稱為阻塞(blocking)。
但如果你希望服務器僅僅注意檢查是否有客戶在等待連接,有就接受連接;否則就繼續做其他事情,則可以通過將 socket設置為非阻塞方式來實現:非阻塞socket在沒有客戶在等待時就使accept調用立即返回 。
通過設置socket為非阻塞方式,可以實現“輪詢”若干socket。當企圖從一個沒有數據等待處理的非阻塞socket讀入數據時,函數將立即返回,并且返回值置為-1,并且errno置為EWOULDBLOCK。但是這種“輪詢”會使CPU處于忙等待方式,從而降低性能。考慮到這種情況,假設你希望服務器監聽連接服務請求的同時從已經建立的連接讀取數據,你也許會想到用一個accept語句和多個recv()語句,但是由于accept及recv都是會阻塞的,所以這個想法顯然不會成功。
調用非阻塞的socket會大大地浪費系統資源。而調用select()會有效地解決這個問題,它允許你把進程本身掛起來,而同時使系統內核監聽所要求的一組文件描述符的任何活動,只要確認在任何被監控的文件描述符上出現活動,select()調用將返回指示該文件描述符已準備好的信息,從而實現了為進程選出隨機的變化,而不必由進程本身對輸入進行測試而浪費CPU開銷。

其次,并發服務器,在上述cycletcpserver.c中,由于使用了fork技術也可以稱之為并發服務器,但這種服務器并不是真正意義上的IO多路復用的并發服務器,并且由于沒有處理阻塞問題,實際應用有各種各樣的問題。

一個典型IO多路復用的單進程并發服務器流程如下:
/*IO多路復用并發服務流程圖*/


下面是一個演示IO多路復用的源程序,是一個端口轉發程序,但它的用處相當大,實際應用中的各類代理軟件或端口映射軟件都是基于這樣的代碼的,比如Windows下的WinGate、WinProxy等都是在此基礎上實現的。源代碼如下:
/*----------------------源代碼開始--------------------------------------------*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <string.h>
#include <signal.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>


static int forward_port;

#undef max
#define max(x,y) ((x) > (y) ? (x) : (y))

/*************************關于本文檔************************************
*filename: tcpforwardport.c
*purpose: 演示了select的用法,這是一個極好的代理軟件核心,專門作端口映射用
*tidied by: zhoulifa(zhoulifa@163.com) 周立發(http://zhoulifa.bokee.com)
Linux愛好者 Linux知識傳播者 SOHO族 開發者 最擅長C語言
*date time:2006-07-05 19:00:00
*Note: 任何人可以任意復制代碼并運用這些文檔,當然包括你的商業用途
* 但請遵循GPL
*Thanks to: Paul Sheer 感謝Paul Sheer在select_tut的man手冊里提供了這份源代碼
*Hope:希望越來越多的人貢獻自己的力量,為科學技術發展出力
*********************************************************************/

static int listen_socket (int listen_port) {
    struct sockaddr_in a;
    int s;
    int yes;
    if ((s = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
        perror ("socket");
        return -1;
    }
    yes = 1;
    if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &yes, sizeof (yes)) <
0) {
        perror ("setsockopt");
        close (s);
        return -1;
    }
    memset (&a, 0, sizeof (a));

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美在线观看你懂的| 久久久99精品久久| 日韩欧美一二三| 久久久久久黄色| 中文字幕制服丝袜成人av| 午夜久久久影院| 亚洲国产美女搞黄色| 久久99精品久久久| 欧美日韩中文精品| 国产精品网曝门| 韩国女主播一区| 91精品国产综合久久蜜臀| 亚洲欧美怡红院| 国产精品88av| 欧美videossexotv100| 一区二区三区**美女毛片| 成人午夜在线视频| wwwwxxxxx欧美| 美国三级日本三级久久99| 欧美亚洲一区二区在线观看| 国产精品视频一二| 国产成人精品www牛牛影视| 在线不卡一区二区| 亚洲一级二级在线| 色悠悠久久综合| 亚洲欧美偷拍卡通变态| 粉嫩av一区二区三区在线播放 | 欧美老女人在线| 一区二区三区日韩在线观看| 99久久精品免费看| 中文字幕一区免费在线观看| 国产aⅴ精品一区二区三区色成熟| 久久综合资源网| 狠狠色丁香九九婷婷综合五月 | 色av综合在线| 亚洲免费在线电影| 欧美在线视频全部完| 一区二区三国产精华液| 91国产免费观看| 亚洲成a人片在线不卡一二三区| 欧美午夜不卡在线观看免费| 久久er精品视频| 精品免费视频.| 国产一区二区福利视频| 国产精品五月天| 99国产麻豆精品| 亚洲大片在线观看| 欧美一级黄色大片| 国产 日韩 欧美大片| 亚洲欧洲国产日韩| 欧美性一二三区| 日韩**一区毛片| 国产欧美一二三区| 色天使色偷偷av一区二区| 一区二区久久久久| 欧美一级一区二区| 国产一区二区看久久| 国产精品国产三级国产普通话三级 | 久久成人18免费观看| 久久亚洲私人国产精品va媚药| 高清av一区二区| 亚洲成av人片一区二区三区| 欧美一级久久久久久久大片| 国产成人在线电影| 亚洲精品videosex极品| 欧美一区二区三区视频在线| 国产69精品久久777的优势| 伊人色综合久久天天| 精品久久人人做人人爰| av电影在线观看完整版一区二区| 一区二区欧美国产| 久久综合五月天婷婷伊人| 91在线视频18| 另类成人小视频在线| 亚洲欧美偷拍另类a∨色屁股| 日韩欧美国产麻豆| 91浏览器在线视频| 国产不卡免费视频| 亚洲一区二区三区在线看| 亚洲精品一线二线三线无人区| 91视频国产资源| 激情成人综合网| 亚洲一区二区三区四区五区黄 | 亚洲综合精品自拍| 欧美xxxxxxxxx| 在线区一区二视频| 国产成人av自拍| 麻豆精品在线视频| 夜夜操天天操亚洲| 日本一区二区成人| 欧美大度的电影原声| 欧洲亚洲国产日韩| www.成人在线| 成人午夜精品一区二区三区| 蜜臀va亚洲va欧美va天堂| 亚洲在线观看免费视频| 国产精品欧美一级免费| 欧美va在线播放| 91精品免费观看| 欧美精品在线一区二区| 日本高清不卡在线观看| 成人91在线观看| 粉嫩高潮美女一区二区三区| 国产自产v一区二区三区c| 天堂va蜜桃一区二区三区漫画版| 亚洲免费观看高清完整| 国产精品女主播av| 亚洲国产精品精华液ab| 欧美xingq一区二区| 欧美一区二区在线视频| 91麻豆精品国产91久久久久久久久 | 视频一区免费在线观看| 中文字幕亚洲视频| 中文字幕在线一区免费| 国产精品少妇自拍| 中文字幕一区不卡| 亚洲欧洲综合另类| 亚洲一区二区三区精品在线| 亚洲一区二区三区中文字幕在线| 亚洲一区二区综合| 亚洲va欧美va人人爽午夜| 亚洲成人777| 婷婷六月综合亚洲| 青青草原综合久久大伊人精品优势| 亚洲成年人影院| 日本女人一区二区三区| 日本vs亚洲vs韩国一区三区二区| 日本欧美一区二区三区乱码| 六月丁香综合在线视频| 国产在线精品一区二区不卡了| 国产精品影音先锋| av成人动漫在线观看| 色综合天天综合网国产成人综合天 | 日本不卡一区二区三区高清视频| 午夜电影一区二区三区| 蜜臀久久99精品久久久画质超高清 | 日韩伦理电影网| 亚洲男人的天堂网| 肉丝袜脚交视频一区二区| 麻豆91精品视频| 成人高清视频在线| 欧美艳星brazzers| 日韩三级电影网址| 亚洲国产成人在线| 夜夜精品视频一区二区| 久久精品国产99| www.亚洲免费av| 制服丝袜中文字幕亚洲| 久久久99免费| 亚洲第一成年网| 国产精品综合视频| 在线影视一区二区三区| 91麻豆精品国产91久久久久久久久| 久久色在线观看| 一区二区三区在线播放| 精品一区二区三区不卡| 一本色道久久综合亚洲aⅴ蜜桃 | 91香蕉视频在线| 欧美一区二区日韩| 亚洲欧洲色图综合| 免费的国产精品| 91欧美激情一区二区三区成人| 欧美一区二区三区婷婷月色| 国产精品人妖ts系列视频| 免费人成精品欧美精品| av色综合久久天堂av综合| 日韩欧美色综合网站| 一区二区三区在线视频免费观看| 国产一区二区三区在线观看免费视频| 色婷婷国产精品| 国产视频911| 男女视频一区二区| 在线视频国内自拍亚洲视频| 日本一区二区高清| 精品一区二区影视| **性色生活片久久毛片| 日韩va欧美va亚洲va久久| 91视视频在线观看入口直接观看www | 国产成人免费xxxxxxxx| 91精品欧美福利在线观看| 一区二区欧美在线观看| 成人av集中营| 国产婷婷色一区二区三区在线| 免费看日韩精品| 欧美午夜精品电影| 夜夜嗨av一区二区三区| 91丝袜美腿高跟国产极品老师| 欧美激情一二三区| 国产精品白丝av| 久久婷婷成人综合色| 精品在线观看视频| 日韩美女视频一区二区在线观看| 亚洲成av人片观看| 欧美视频完全免费看| 亚洲永久精品国产| 欧美日韩一级二级| 性做久久久久久久久| 欧美日韩精品系列| 五月天中文字幕一区二区| 欧美精品99久久久**|