




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)1 第三章、迭代服務(wù)器與客戶端第三章、迭代服務(wù)器與客戶端 nTCP套接字編程基本步驟套接字編程基本步驟 n套接字編程基本函數(shù)套接字編程基本函數(shù) n迭代迭代echo服務(wù)器服務(wù)器 n迭代迭代echo客戶端客戶端 n測試用例測試用例 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)2 1. TCP套接字編程基本步驟套接字編程基本步驟 nTCP套接字基本步驟分為服務(wù)器端和客戶端兩部分:套接字基本步驟分為服務(wù)器端和客戶端兩部分: n服務(wù)器端服務(wù)器端 v創(chuàng)建套接字創(chuàng)建套接字 v綁定套接字綁定套接字 v設(shè)置套接字為監(jiān)聽模式,進(jìn)入被動(dòng)接受連接狀態(tài)設(shè)置套接字為監(jiān)聽模式,進(jìn)入被動(dòng)接受連接狀態(tài) v接受請(qǐng)求,建立連接接受請(qǐng)求,建立連
2、接 v讀寫數(shù)據(jù)讀寫數(shù)據(jù) v終止連接終止連接 n客戶端步驟客戶端步驟 v創(chuàng)建套接字創(chuàng)建套接字 v與遠(yuǎn)程服務(wù)器建立連接與遠(yuǎn)程服務(wù)器建立連接 v讀讀/寫數(shù)據(jù)寫數(shù)據(jù) 終止連接終止連接 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)3 TCP套接字編程(套接字編程(cont.) socket() bind() listen() accept() read() write() close() socket() connect() write() read() close() 阻塞直到接收 到客戶連接請(qǐng)求 TCP服務(wù)器端 TCP客戶端 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)4 2. 套接字編程基本函數(shù)套接字編程基本函數(shù) n bind函數(shù)函數(shù) #include
3、 int bind(int sockfd, struct sockaddr *addr, socklen_len len) 返回:返回:0成功;成功;-1出錯(cuò)出錯(cuò) n 該函數(shù)用于給傳輸層的該函數(shù)用于給傳輸層的socket分配地址,其深層含義是在分配地址,其深層含義是在 分用分用Packet的時(shí)候,協(xié)議棧通過檢查的時(shí)候,協(xié)議棧通過檢查inpcb中的地址,確中的地址,確 定定packet應(yīng)該傳送給哪個(gè)應(yīng)該傳送給哪個(gè)socket n 一般而言,服務(wù)器調(diào)用此函數(shù),而客戶則很少調(diào)用它。一般而言,服務(wù)器調(diào)用此函數(shù),而客戶則很少調(diào)用它。 n 綁定地址時(shí),可以指定地址和端口號(hào),也可以指定其中之綁定地址時(shí),可以
4、指定地址和端口號(hào),也可以指定其中之 一,甚至一個(gè)也不指定。通配地址:一,甚至一個(gè)也不指定。通配地址:INADDR_ANY 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)5 bind函數(shù)(續(xù))函數(shù)(續(xù)) n 另外,需要注意以下幾點(diǎn):另外,需要注意以下幾點(diǎn): 參數(shù)參數(shù)addr中的相關(guān)字段在初始化時(shí),必須是網(wǎng)絡(luò)字節(jié)中的相關(guān)字段在初始化時(shí),必須是網(wǎng)絡(luò)字節(jié) 序;序; 如果由內(nèi)核來選擇如果由內(nèi)核來選擇IP地址和臨時(shí)端口號(hào),函數(shù)并不返地址和臨時(shí)端口號(hào),函數(shù)并不返 回所選擇的值。為了獲得這些值,進(jìn)程必須調(diào)用回所選擇的值。為了獲得這些值,進(jìn)程必須調(diào)用 getsockname函數(shù)函數(shù) 函數(shù)函數(shù)bind返回的一個(gè)常見錯(cuò)誤是:返回的一個(gè)常見錯(cuò)誤是
5、:EADDRINUSE,我,我 們可以通過設(shè)置套接口選項(xiàng)們可以通過設(shè)置套接口選項(xiàng)SO_REUSEADDR。 IP地址地址端口端口結(jié)果結(jié)果 通配地址通配地址0內(nèi)核選擇內(nèi)核選擇IP地址和端口號(hào)地址和端口號(hào) 通配地址通配地址非非0 內(nèi)核選擇內(nèi)核選擇IP地址,進(jìn)程指定端口地址,進(jìn)程指定端口 本地本地IP0 進(jìn)程指定進(jìn)程指定IP地址,內(nèi)核選擇端口地址,內(nèi)核選擇端口 本地本地IP非非0 進(jìn)程指定進(jìn)程指定IP地址和端口號(hào)地址和端口號(hào) 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)6 bind函數(shù)的用法函數(shù)的用法 struct sockaddr_in addr; int port = 1234; addr.sin_family = AF_
6、INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(port); if (bind(fd, (struct sockaddr *) 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)8 listen函數(shù)(續(xù))函數(shù)(續(xù)) 三路握手完成 兩隊(duì)列之和不能 超過backlog 已完成連接隊(duì)列 (ESTABLISHED狀態(tài)) 未完成連接隊(duì)列 (SYN_RCVD狀態(tài)) 新到達(dá)的SYN分節(jié) 服務(wù)器 accept 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)9 Client Server Socket Connect(blocks) (active open) Socket,bind
7、,listen (passive open)SYN J SYN K, ack J+1 ack K+1 Accept return Read (blocks) Connect return 連接完成,連接完成, 進(jìn)入已建連隊(duì)列進(jìn)入已建連隊(duì)列 RTT 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)10 listen函數(shù)(續(xù))函數(shù)(續(xù)) n 另外幾點(diǎn)說明:另外幾點(diǎn)說明: 不同的實(shí)現(xiàn)對(duì)不同的實(shí)現(xiàn)對(duì)backlog有不同的解釋,如源自有不同的解釋,如源自 Berkeley的實(shí)現(xiàn)將的實(shí)現(xiàn)將backlog增加一個(gè)模糊因子,把它增加一個(gè)模糊因子,把它 乘以乘以1.5,再作為兩個(gè)隊(duì)列之和;,再作為兩個(gè)隊(duì)列之和; 不要把不要把backlog定義
8、為定義為0,因?yàn)橛行?shí)現(xiàn)允許,因?yàn)橛行?shí)現(xiàn)允許1個(gè)連接個(gè)連接 排隊(duì),而有些實(shí)現(xiàn)不允許連接排隊(duì);排隊(duì),而有些實(shí)現(xiàn)不允許連接排隊(duì); 當(dāng)一個(gè)客戶當(dāng)一個(gè)客戶SYN到達(dá)時(shí),若兩個(gè)隊(duì)列都是滿的,到達(dá)時(shí),若兩個(gè)隊(duì)列都是滿的,tcp就就 忽略此分節(jié),且不發(fā)送忽略此分節(jié),且不發(fā)送RST。這是因?yàn)?,這種情況是。這是因?yàn)椋@種情況是 暫時(shí)的,客戶暫時(shí)的,客戶tcp將重發(fā)將重發(fā)SYN,期望不久的將來就能在,期望不久的將來就能在 隊(duì)列中找到空閑條目。隊(duì)列中找到空閑條目。 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)11 基本套接字函數(shù)基本套接字函數(shù)accept #include int accept(int sockfd, struct sock
9、addr *cliaddr, socklen_t *addrlen); 返回:非負(fù)描述字返回:非負(fù)描述字OK;-1出錯(cuò);出錯(cuò); n accept函數(shù)由函數(shù)由TCP服務(wù)器調(diào)用;從已完成連接隊(duì)列頭返回服務(wù)器調(diào)用;從已完成連接隊(duì)列頭返回 下一個(gè)已完成連接;如果該隊(duì)列空,則進(jìn)程進(jìn)入睡眠狀態(tài)。下一個(gè)已完成連接;如果該隊(duì)列空,則進(jìn)程進(jìn)入睡眠狀態(tài)。 n 函數(shù)返回的套接字為連接套接字,應(yīng)與監(jiān)聽套接字區(qū)分開函數(shù)返回的套接字為連接套接字,應(yīng)與監(jiān)聽套接字區(qū)分開 來來 n 該函數(shù)最多該函數(shù)最多:一個(gè)既可能是新套接字也可能是:一個(gè)既可能是新套接字也可能是 錯(cuò)誤指示的整數(shù),一個(gè)客戶進(jìn)程的協(xié)議地址(由錯(cuò)誤指示的整數(shù),一個(gè)客
10、戶進(jìn)程的協(xié)議地址(由cliaddr 所指),以及該地址的大?。ㄟ@后兩個(gè)參數(shù)是值結(jié)果參所指),以及該地址的大?。ㄟ@后兩個(gè)參數(shù)是值結(jié)果參 數(shù));也就是說,服務(wù)器可以通過參數(shù)數(shù));也就是說,服務(wù)器可以通過參數(shù)cliaddr來得到請(qǐng)來得到請(qǐng) 求連接并獲得成功的客戶的地址和端口號(hào);求連接并獲得成功的客戶的地址和端口號(hào); 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)12 accept函數(shù)示例函數(shù)示例 struct sockaddr_in servaddr, cliaddr; socklen_tlen; int listenfd, connfd; connfd = accept(listenfd, (struct sockaddr *
11、) if (connfd = -1) /* 出錯(cuò)處理出錯(cuò)處理 */ printf(“ connection from %s, port = %dn”, inet_ntop(AF_INET, cliaddr.sin_addr, buff, sizeof(buf), ntons(cliaddr.sin_port); 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)13 基本套接字函數(shù)基本套接字函數(shù)connect #include int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 返回:返回:0成功;成功;-1出錯(cuò)出錯(cuò); n 函數(shù)函數(shù)c
12、onnect激發(fā)激發(fā)TCP的三路握手過程;僅在成功或出錯(cuò)返回;錯(cuò)誤有的三路握手過程;僅在成功或出錯(cuò)返回;錯(cuò)誤有 以下幾種情況:以下幾種情況: 如果客戶沒有收到如果客戶沒有收到SYN分節(jié)的響應(yīng)(總共分節(jié)的響應(yīng)(總共75秒,這之間需要可能需秒,這之間需要可能需 要重發(fā)若干次要重發(fā)若干次SYN),則返回),則返回ETIMEDOUT。 如果對(duì)客戶的如果對(duì)客戶的SYN的響應(yīng)是的響應(yīng)是RST,則表明該服務(wù)器主機(jī)在該端口上,則表明該服務(wù)器主機(jī)在該端口上 沒有進(jìn)程在等待。函數(shù)返回錯(cuò)誤沒有進(jìn)程在等待。函數(shù)返回錯(cuò)誤ECONNREFUSED; 如果客戶發(fā)出的如果客戶發(fā)出的SYN在中間路由器上引發(fā)一個(gè)目的地不可達(dá)在中
13、間路由器上引發(fā)一個(gè)目的地不可達(dá)ICMP錯(cuò)錯(cuò) 誤,則如第一種情況,連續(xù)發(fā)送誤,則如第一種情況,連續(xù)發(fā)送SYN,直到規(guī)定時(shí)間,返回,直到規(guī)定時(shí)間,返回 EHOSTUNREACH或或ENETUNREACH。 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)14 connect函數(shù)(續(xù))函數(shù)(續(xù)) n 客戶在調(diào)用客戶在調(diào)用connect前不必非得調(diào)用前不必非得調(diào)用bind函數(shù),此時(shí),內(nèi)函數(shù),此時(shí),內(nèi) 核會(huì)選擇一個(gè)合適的核會(huì)選擇一個(gè)合適的IP地址和臨時(shí)端口號(hào);地址和臨時(shí)端口號(hào); n 如果函數(shù)如果函數(shù)connect失敗,則套接字不可再用,必須關(guān)閉。失敗,則套接字不可再用,必須關(guān)閉。 不能再對(duì)此套接字再調(diào)用函數(shù)不能再對(duì)此套接字再調(diào)用函數(shù)c
14、onnect。 注意這一點(diǎn)!注意這一點(diǎn)! 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)15 3. echo服務(wù)器服務(wù)器 n 本課程全程采用本課程全程采用echo程序作為講解的例子程序作為講解的例子 n 采用這個(gè)例子的原因采用這個(gè)例子的原因 操作簡單,關(guān)注于網(wǎng)絡(luò)編程本身操作簡單,關(guān)注于網(wǎng)絡(luò)編程本身 便于比較各種網(wǎng)絡(luò)編程技術(shù)的性能便于比較各種網(wǎng)絡(luò)編程技術(shù)的性能 Hello, world! Hello, world! Hello, world! Hello, world! 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)16 echo服務(wù)器服務(wù)器 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)17 int main(int argc, char *argv) int fd1, fd2;
15、socklen_t length; struct sockaddr_in addr1, addr2; char bufBUFSIZE; / / create a socket / if (fd1 = socket(AF_INET, SOCK_STREAM, 0) = -1) cout strerror(errno) endl; return -1; 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)18 / / bind the socket / bzero( addr1.sin_family = AF_INET; addr1.sin_port = htons(LISTEN_PORT); addr1.sin_addr.s_ad
16、dr = htonl(INADDR_ANY); if (bind(fd1, (struct sockaddr *) return -1; 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)19 / / listen the socket / if (listen(fd1, BACKLOG) 0) cout strerror(errno) endl; return -1; / / serve the client / while (true) / / accept the requirement of some client / 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)20 length = sizeof(addr2); bzero( if (fd2
17、= accept(fd1, (struct sockaddr *) return -1; else / / echo the client / if (tcpecho(fd2, buf, BUFSIZE) = -1) break; 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)21 / / close the listening socket / close(fd1); return 0; 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)22 4. echo客戶端程序客戶端程序 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)23 int main(int argc, char *argv) int ret, fd; struct sockaddr_in addr; char bufB
18、UFFERSIZE; / / get the servers addr / if (argc != 2) printf(Usage: iterateClient addrn); return -1; 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)24 bzero( addr.sin_family = AF_INET; addr.sin_port = htons(LISTEN_PORT); if (!inet_pton(AF_INET, argv1, (void *) return -1; / / create a socket / if (fd = socket(AF_INET, SOCK_STREAM, 0) = -1)
19、 printf(%sn, strerror(errno); return -1; 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)25 / / connect to the server / RETRY: if (connect(fd, (struct sockaddr *) else printf(%sn, strerror(errno); return -1; 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)26 / / get the serve / return tcpclient(fd, buf, BUFFERSIZE); n tcpclient()函數(shù)中使用函數(shù)中使用read、write函數(shù)向標(biāo)準(zhǔn)輸入、標(biāo)函數(shù)向標(biāo)準(zhǔn)輸入、標(biāo) 準(zhǔn)輸出讀寫數(shù)據(jù),為什么沒有用準(zhǔn)輸出讀寫數(shù)據(jù),為什么沒有用fgets? 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)27 5. 測試用例測試用例 n 1. 基本功能基本功能 打開服務(wù)器打開服務(wù)器 netstat antp 打開客戶端打開客戶端 netstat antp ps a 輸入字符串輸入字符串 Ctrl-D netstat -antp 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)28 n 2. 觀察報(bào)文觀察報(bào)文 sudo tcpdump tcp port 1234 Xu i lo 分析分析TCP報(bào)文結(jié)構(gòu)報(bào)文結(jié)構(gòu) 互聯(lián)網(wǎng)絡(luò)程序設(shè)計(jì)29 n 3. 多客戶端測試多客戶端測試 首先以一個(gè)客戶端連接,獲取服務(wù);首先以一個(gè)客戶端
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 瓷磚鋪貼工崗位面試問題及答案
- 2025屆河南天一大聯(lián)考高一化學(xué)第二學(xué)期期末預(yù)測試題含解析
- 培養(yǎng)質(zhì)量評(píng)價(jià)管理辦法
- 醫(yī)藥產(chǎn)品登記管理辦法
- 權(quán)力清單管理辦法麗水
- 辦公區(qū)域日常管理辦法
- 民航安檢道口管理辦法
- 北京特殊班級(jí)管理辦法
- 碳中和目標(biāo)下鋰離子電池健康狀態(tài)評(píng)估體系構(gòu)建研究
- 醫(yī)療器材資質(zhì)管理辦法
- (高級(jí))數(shù)據(jù)安全管理員職業(yè)技能鑒定考試題庫-實(shí)操題
- 初三化學(xué)上冊第一單元測試題(含答案)
- 移動(dòng)通信網(wǎng)絡(luò)優(yōu)化服務(wù)合同
- (正式版)SH∕T 3548-2024 石油化工涂料防腐蝕工程施工及驗(yàn)收規(guī)范
- JBT 14449-2024 起重機(jī)械焊接工藝評(píng)定(正式版)
- DL-T5017-2007水電水利工程壓力鋼管制造安裝及驗(yàn)收規(guī)范
- 海上風(fēng)電場選址與環(huán)境影響評(píng)估
- 《陸上風(fēng)電場工程概算定額》(NB-T 31010-2019)
- 《早期教育概論》課程標(biāo)準(zhǔn)
- 藥物分析年終述職報(bào)告
- 農(nóng)發(fā)行信貸業(yè)務(wù)考試題庫題庫附答案
評(píng)論
0/150
提交評(píng)論