青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

依舊的博客

技術(shù)學(xué)習(xí)

C++博客 首頁 新隨筆 聯(lián)系 聚合 管理
  17 Posts :: 1 Stories :: 2 Comments :: 0 Trackbacks

1. 客戶-服務(wù)器通信中的基本問題

客戶和服務(wù)器通信是為了使用服務(wù),為此在傳輸機(jī)制的基礎(chǔ)上設(shè)計協(xié)議,通過對通信行為的規(guī)范,實現(xiàn)通信的目的,并解決傳輸中的問題。

傳輸機(jī)制通常由下層協(xié)議提供,根據(jù)不同的通信需要選擇不同的下層協(xié)議,這是一個基本的問題。對應(yīng)用協(xié)議來說,可用的傳輸機(jī)制有可靠連接的字節(jié)流類型和不可靠無連接的數(shù)據(jù)報類型。

服務(wù)器處理大量客戶的請求,從而并發(fā)是服務(wù)器的一個基本問題,如何處理這個問題也取決于通信需要。處理方式上,服務(wù)器可以是循環(huán)的或并發(fā)的,并發(fā)服務(wù)器有多種實現(xiàn)方式(異步I/O,多線程和多進(jìn)程)。

一件事情能無重復(fù)地連續(xù)進(jìn)行,通常會獲得更好的效率,這要求主體始終知道當(dāng)前的狀態(tài)。一次通信過程的連續(xù)性取決于通信雙方,它們都要知道通信進(jìn)行的狀態(tài)。這對客戶一般不成問題,但服務(wù)器要和大量客戶通信,不一定能為每個客戶的每次通信保存狀態(tài)。如果服務(wù)器是有狀態(tài)的,那么就更快地計算響應(yīng),減少通信的數(shù)據(jù)量。但是傳輸和客戶的故障使有狀態(tài)服務(wù)器面臨很大問題,當(dāng)傳輸不可靠(報文重復(fù),丟失,亂序)時,服務(wù)器維護(hù)的狀態(tài)會和客戶失去一致,一個不斷崩潰重啟的客戶會造成狀態(tài)信息不能發(fā)揮作用,而維護(hù)開銷卻極大增加。

這就提出了客戶-服務(wù)器通信中的三個基本問題,它們的解決方案都取決于實際需要,客戶-服務(wù)器通信中有哪些情況的需要呢?

  • 是否要求可靠傳輸;
  • 是否需要服務(wù)器進(jìn)行大量處理。對循環(huán)服務(wù)器進(jìn)行分析可以知道,需要大量處理的通信用循環(huán)方案可能會丟失請求,用并發(fā)方案還可以提高服務(wù)器資源利用率,改善性能,只要少量處理的通信則無法忍受開銷大的解決方案。
  • 在局域網(wǎng)還是互聯(lián)網(wǎng)環(huán)境下,局域網(wǎng)中傳輸很少出錯,互聯(lián)網(wǎng)環(huán)境則不然;


通常根據(jù)前兩個基本問題把服務(wù)器實現(xiàn)分為四種類型,它們的適用范圍如下:

  • 循環(huán)無連接服務(wù)器,少量處理的通信時,并且在局域網(wǎng)中或不要求可靠傳輸。這種做法主要是為了避免開銷。
  • 循環(huán)連接服務(wù)器,較少用,主要是循環(huán)的方式不夠高效,因為連接有一定開銷,響應(yīng)時間可能不低。在少量處理并要求可靠性的情況下使用。
  • 并發(fā)無連接服務(wù)器,很少用,因為要給每個請求開線程,開銷太大。在不要求可靠性的情況下,如果線程開銷遠(yuǎn)小于計算響應(yīng)開銷,或者并發(fā)可以讓各請求的I/O并行,或者循環(huán)方案會丟失請求時可以考慮。
  • 并發(fā)連接服務(wù)器,常用。


2. winsock基本函數(shù)的使用

winsock的基本函數(shù)有WSAStartup(),WSACleanup(),socket(),closesocket(),bind(),listen(),accept(), connect(),send()和recv()。

使用這些函數(shù),客戶端的大概算法是,

  1.  調(diào)用WSAStartup()初始化winsock庫。
  2.  調(diào)用socket()創(chuàng)建套接字,返回套接字描述符s。
  3.  指定遠(yuǎn)程套接字地址sa,對s調(diào)用connect(),向sa標(biāo)識的服務(wù)進(jìn)程請求連接。
  4.  連接成功后,對s調(diào)用send()發(fā)送請求,調(diào)用recv()接收響應(yīng),如此反復(fù)直到完成任務(wù)。
  5.  對s調(diào)用closesocket()關(guān)閉連接。
  6.  不再發(fā)起連接處理新的任務(wù)時,調(diào)用WSACleanup()釋放winsock庫。

服務(wù)器端的大概算法是,

  1. 調(diào)用WSAStartup()初始化winsock庫。
  2. 調(diào)用socket()創(chuàng)建套接字,返回套接字描述符s。
  3. 對s調(diào)用bind(),將其綁定到本地的套接字sa。
  4. 調(diào)用listen(),將s置為被動模式。此時開始偵聽客戶端的連接請求,將其放入一個隊列。
  5. 對s調(diào)用accept(),即從請求隊列中取出一項,接受該連接后返回一個新的套接字描述符s',以及對應(yīng)客戶端的套接字地址sa'。
  6. 對s'調(diào)用recv()接收請求,調(diào)用send()發(fā)送響應(yīng),如此反復(fù)直到完成任務(wù)。
  7. 對s'調(diào)用closesocket()關(guān)閉該連接。
  8. 重復(fù)5到7的過程。
  9. 從8退出后,調(diào)用WSACleanup()釋放winsock庫。

有以下幾點需要進(jìn)一步說明,

1). 客戶端調(diào)用connect()和服務(wù)器端調(diào)用accept()成功后將在客戶進(jìn)程和服務(wù)器進(jìn)程之間建立一個TCP連接。連接兩端的每個套接字描述符都包含一個本地端點地址和一個遠(yuǎn)程端點地址。所以在使用連接套接字發(fā)送數(shù)據(jù)時不用指示目的地址。

2). 多宿主主機(jī)的IP地址選擇問題。從上面的算法容易提出這樣的問題,為什么客戶端在使用套接字時不綁定端點地址?通常的主機(jī)只有一個IP,但是多宿主主機(jī)有多個IP地址,在這種情況下,客戶端為套接字指定的IP可能與實際發(fā)送時經(jīng)過的IP不符,所以允許客戶端不指定套接字地址,而由TCP/IP軟件在實際發(fā)送時指定IP,同時選擇一個未用過的端口號,這正是在connect()調(diào)用中完成的。那么服務(wù)器端就不存在同樣的情況嗎?不是,在它調(diào)用bind()時指定一個套接字地址,其端口部分采用應(yīng)用協(xié)議的熟知端口,而IP地址部分有著同樣的問題。為此定義了一個代表統(tǒng)配地址的常量INADDR_ANY,用它指示IP地址部分。實際使用的IP仍然是由TCP/IP軟件分配。

3). TCP為一個連接的發(fā)送端和接收端各維護(hù)一個緩沖區(qū)。當(dāng)發(fā)送端緩沖區(qū)滿的時候,send()調(diào)用會阻塞,在接收端緩沖區(qū)為空的時候,recv()調(diào)用會阻塞。為什么要在通信進(jìn)程和TCP連接之間維護(hù)一個間接層呢?可能是為了在一端有多個進(jìn)程要使用信道的情況下,在多個進(jìn)程之間進(jìn)行信道分配的協(xié)調(diào)。比如在發(fā)送端,信道傳輸數(shù)據(jù)時send()調(diào)用可以繼續(xù)執(zhí)行,多個進(jìn)程的send()調(diào)用同緩沖區(qū)打交道,彼此影響不大,因為讀寫緩沖區(qū)速度很快,而信道同緩沖區(qū)打交道,這時可以對各進(jìn)程的發(fā)送數(shù)據(jù)進(jìn)行協(xié)調(diào),實現(xiàn)公平的信道分配。另外,在TCP中有滑動窗口概念,是用于流量控制的,前述緩沖區(qū)和滑動窗口有什么關(guān)系?我現(xiàn)在不太清楚。

4). 套接字的關(guān)閉問題。在客戶機(jī)和服務(wù)器通過TCP連接完成數(shù)據(jù)交換后,有一個安全關(guān)閉的問題。一方面,服務(wù)器不能關(guān)閉連接,因為客戶機(jī)可能還有請求,另一方面,客戶機(jī)雖然知道何時不再請求,但是它不知道服務(wù)器的響應(yīng)何時發(fā)送完,因為有些應(yīng)用協(xié)議的響應(yīng)數(shù)據(jù)量不確定。為此采用部分關(guān)閉的辦法,雖然連接是雙向的,但是允許在一個方向上關(guān)閉它,當(dāng)客戶端不再請求時,可以部分關(guān)閉連接,使服務(wù)器收到一個信號,如果響應(yīng)發(fā)送完了,服務(wù)器就可以關(guān)閉連接,此時連接被完全關(guān)閉

3. 套接字接口中的端點地址

端點地址用來表示通信的進(jìn)程,是傳輸層協(xié)議及其套接字接口中的重要概念。不同的協(xié)議族可以用不同方式表示端點地址,一個協(xié)議族還可以有多個地址族,每個地址族的地址格式不同。TCP/IP只有一個地址族,它的端點地址包括一個32位IP地址和一個16位端口號。在協(xié)議族和地址族的基礎(chǔ)上,套接字接口用更為具體的結(jié)構(gòu)來表示端點地址。

套接字是一種適用于多個協(xié)議族的接口,并允許一個協(xié)議族使用多個地址族。TCP/IP協(xié)議族及其唯一地址族的標(biāo)識分別是PF_INET和AF_INET。由于套接字接口的通用性,它提供一個通用的地址結(jié)構(gòu),其格式為(地址族,該族中的套接字地址)。套接字作為一個接口標(biāo)準(zhǔn),可以有不同實現(xiàn),以下我們只討論windows套接字。

如下定義的sockaddr實現(xiàn)了前述通用地址結(jié)構(gòu),

// winsock2.h

struct sockaddr {
        u_short sa_family;              /* address family */
        char    sa_data[14];            /* up to 14 bytes of direct address */
};

sockaddr的通用性是相對的,某些地址族不適合這個結(jié)構(gòu)。

盡管sockaddr適合于TCP/IP協(xié)議族,但是winsock還定義了TCP/IP專用的地址格式,

// winsock2.h

struct sockaddr_in {
        short   sin_family;
        u_short sin_port;
        struct  in_addr sin_addr;
        char    sin_zero[8];
};

sin_family域取值恒為AF_INET。其中的in_addr結(jié)構(gòu)表示IP地址,定義如下,

//winsock2.h

struct in_addr {
        union {
                struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
                struct { u_short s_w1,s_w2; } S_un_w;
                u_long S_addr;
        } S_un;
#define s_addr  S_un.S_addr
                                /* can be used for most TCP & IP code */
#define s_host  S_un.S_un_b.s_b2
                                /* host on imp */
#define s_net   S_un.S_un_b.s_b1
                                /* network */
#define s_imp   S_un.S_un_w.s_w2
                                /* imp */
#define s_impno S_un.S_un_b.s_b4
                                /* imp # */
#define s_lh    S_un.S_un_b.s_b3
                                /* logical host */
};

為了保證軟件的可移植性與可維護(hù)性,訪問TCP/IP的代碼不應(yīng)使用sockaddr。只使用TCP/IP的應(yīng)用程序可以只使用sockaddr_in,而永遠(yuǎn)不用sockaddr。

4. winsock程序?qū)嵗?/p>

《vc6技術(shù)內(nèi)幕》的例程ex34a包括一個web服務(wù)器和三個客戶,服務(wù)器用winsock實現(xiàn),一個客戶用winsock,另兩個用wininet。我們以winsock實現(xiàn)的服務(wù)器和客戶為例。

CBlockingSocket對各接口函數(shù)進(jìn)行封裝,使它們的調(diào)用可以統(tǒng)一報錯。把錯誤檢查和函數(shù)調(diào)用一起封裝可以避免每次調(diào)用這些函數(shù)時都檢錯。為統(tǒng)一報錯,采用了異常機(jī)制,在檢出錯誤后拋出異常,然后統(tǒng)一進(jìn)行異常處理。異常機(jī)制使我們可以把錯誤檢查和錯誤處理分開,檢查必須是分散的,但是處理可以適當(dāng)集中,使代碼簡化。

CHttpBlockingSocket根據(jù)接收http報文的特點對CBlockingSocket進(jìn)行了擴(kuò)展。成員函數(shù)ReadHttpHeaderLine()可以從TCP連接中按行接收字符(它引入了一個緩沖區(qū),緩沖區(qū)中收到的字符構(gòu)成一行后再輸出。該緩沖區(qū)的長度需要能夠容納每一行字符,溢出時報錯。接收輸出行的緩沖區(qū)也可能長度不足,這時接收的數(shù)據(jù)不足一行,在調(diào)用ReadHttpHeaderLine()時要注意這一點),ReadHttpResponse()用于接收首部行之后所有的響應(yīng),當(dāng)調(diào)用者提供的緩沖區(qū)不足時會報錯。緩沖區(qū)不足的情況都是在CBlockingSocket::Receive()函數(shù)中檢測到的,該函數(shù)調(diào)用以上層次中的代碼按照正常情況編寫。

CSockAddr是一個與sockaddr_in同樣用途的類,但是用法更方便。winsock函數(shù)使用的端點地址結(jié)構(gòu)是sockaddr,sockaddr_in本身用來代替它,所以CSockAddr需要能夠替代sockaddr。sockaddr可能用在傳值或傳址參數(shù)中,CSockAddr必須在邏輯上和存儲上都和sockaddr有等價性,并實現(xiàn)有關(guān)強制類型轉(zhuǎn)換。CSockAddr還實現(xiàn)了和sockaddr, sockaddr_in互相轉(zhuǎn)換的成員函數(shù),因為一種結(jié)構(gòu)很難在所有情況下都好用,新結(jié)構(gòu)也需要和舊結(jié)構(gòu)保持兼容。

 

本例中采用服務(wù)器關(guān)閉套接字的辦法,因為每次連接只處理一個請求。

參考:

《用TCP/IP進(jìn)行網(wǎng)際互聯(lián)第三卷(windows套接字版)》/清華出版社

《vc6技術(shù)內(nèi)幕 5th ed》/希望電子出版社

posted on 2006-05-02 12:46 依舊的博客 閱讀(2299) 評論(0)  編輯 收藏 引用 所屬分類: 編程
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久精品一区蜜桃臀影院| 国产精品嫩草久久久久| 欧美激情一区二区三级高清视频 | 国产精品久久久久久久久久免费 | 久久天天躁夜夜躁狠狠躁2022 | 久久av一区二区三区漫画| 西西裸体人体做爰大胆久久久| 一区二区三欧美| 亚洲无人区一区| 久久精品欧美| 欧美福利视频| 亚洲精品在线观看免费| 亚洲日本电影在线| 亚洲精品在线免费观看视频| 在线视频一区二区| 久久国产精品毛片| 欧美华人在线视频| 国产精品豆花视频| 加勒比av一区二区| 亚洲特色特黄| 久久综合福利| 一区二区欧美激情| 久久亚洲欧美| 国产精品美女久久久| 亚洲第一中文字幕| 亚洲综合国产激情另类一区| 久久精品男女| 久久婷婷国产麻豆91天堂| 久久人91精品久久久久久不卡| 久久久久久夜| 99亚洲伊人久久精品影院红桃| 欧美在线亚洲综合一区| 欧美色一级片| 亚洲国产日韩一级| 亚洲国产成人在线播放| 亚洲性色视频| 91久久久亚洲精品| 亚洲福利免费| 国产精品日韩欧美一区| 亚洲国产婷婷| 久久精品视频网| 日韩视频在线免费观看| 久久综合色一综合色88| 国产啪精品视频| 亚洲视频播放| 亚洲精品久久久久久下一站 | 日韩午夜三级在线| 久久综合九色综合久99| 国产伦精品一区二区三区高清| 亚洲黑丝一区二区| 久久一区二区三区四区| 亚洲欧美日韩一区二区三区在线观看 | 欧美日韩在线免费视频| 亚洲片区在线| 蜜臀av一级做a爰片久久| 国产日韩亚洲欧美综合| 午夜久久tv| 亚洲午夜在线观看| 欧美日韩裸体免费视频| 在线国产亚洲欧美| 美女久久一区| 久久九九精品99国产精品| 国内久久婷婷综合| 久久久久久一区二区| 欧美在线观看你懂的| 国产色综合久久| 亚洲欧美文学| 亚洲自拍偷拍麻豆| 国产日韩欧美一二三区| 欧美专区日韩视频| 久久久久久高潮国产精品视| 国产精品免费网站| 久久aⅴ乱码一区二区三区| 小黄鸭视频精品导航| 国内在线观看一区二区三区| 久久天天狠狠| 欧美国产三级| 亚洲香蕉伊综合在人在线视看| 亚洲黄色免费网站| 国产精品久久久久久久免费软件| 亚洲综合视频网| 欧美一区二视频在线免费观看| 黄色亚洲大片免费在线观看| 蜜臀av性久久久久蜜臀aⅴ四虎 | 在线观看日韩av先锋影音电影院| 久久精品人人做人人爽电影蜜月| 久久精品国产亚洲5555| 亚洲国产一二三| 一本色道**综合亚洲精品蜜桃冫 | 欧美一区二区高清| 亚洲风情在线资源站| 亚洲免费黄色| 国产情侣一区| 欧美激情亚洲自拍| 国产精品久久久久久久久动漫| 欧美在线观看一区二区三区| 久久久精品性| 亚洲欧美国产视频| 久久精视频免费在线久久完整在线看| 在线免费观看日韩欧美| 日韩一区二区久久| 永久免费精品影视网站| 日韩视频一区| 亚洲电影在线免费观看| 宅男噜噜噜66一区二区66| 亚洲国产成人av在线| 亚洲桃色在线一区| 亚洲国产日韩在线一区模特| 亚洲一本视频| 99re6热只有精品免费观看| 亚洲欧美日韩在线高清直播| 欧美视频网址| 欧美激情第3页| 国产乱人伦精品一区二区| 亚洲国产成人不卡| 国产欧美综合一区二区三区| 亚洲美女视频在线观看| 亚洲欧洲在线一区| 久久免费99精品久久久久久| 午夜久久电影网| 欧美日韩一区二区欧美激情 | 久久综合色综合88| 国产精品你懂得| 亚洲视频成人| 99av国产精品欲麻豆| 免费美女久久99| 久久婷婷麻豆| 国语自产精品视频在线看| 亚洲欧美一级二级三级| 亚洲一区二区综合| 欧美精品自拍| 91久久香蕉国产日韩欧美9色| 尤物在线精品| 午夜在线精品| 久久久久久久999| 国产亚洲美州欧州综合国| 亚洲视频香蕉人妖| 亚洲欧美视频在线观看视频| 国产精品久久久久影院亚瑟| 日韩天堂在线观看| 日韩视频免费| 欧美色另类天堂2015| 欧美成人精品在线| 国内精品久久久久影院薰衣草| 亚洲欧美日韩电影| 欧美一级片一区| 韩日精品在线| 欧美粗暴jizz性欧美20| 亚洲精品免费一区二区三区| 中文国产一区| 国产农村妇女精品一区二区| 久久亚洲高清| 午夜精品视频在线观看| 亚洲二区视频在线| 鲁大师成人一区二区三区| 免费成人网www| 最新热久久免费视频| 久久综合影视| 日韩网站在线观看| 亚洲欧美日韩综合aⅴ视频| 欧美小视频在线观看| 亚洲制服av| 嫩草伊人久久精品少妇av杨幂| 亚洲国产91| 欧美日韩精品免费看| 午夜精品三级视频福利| 欧美高清视频免费观看| 一区二区三区**美女毛片| 国产九九视频一区二区三区| 欧美在线视频二区| 欧美激情久久久久久| 亚洲午夜羞羞片| 国外成人在线视频| 久久久久国产一区二区三区四区| 韩国av一区二区三区| 免费高清在线视频一区·| 亚洲视频免费| 欧美黄在线观看| 亚洲欧美视频在线观看视频| 亚洲国产毛片完整版| 欧美三级午夜理伦三级中文幕| 亚洲欧美日产图| 亚洲精品久久| 久久人人超碰| 亚欧成人在线| aa日韩免费精品视频一| 国内精品久久久久久| 欧美亚洲成人网| 欧美激情五月| 久久九九国产精品| 亚洲女性喷水在线观看一区| 亚洲国产日韩欧美在线99| 午夜精品久久久久| 99精品久久久| 亚洲国产成人精品女人久久久 | 亚洲直播在线一区| 亚洲欧洲一区二区在线播放| 久久精品一区中文字幕| 亚洲一区二区网站| 亚洲九九爱视频|