版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、西北師范大學(xué)計算機(jī)科學(xué)與工程學(xué)院 學(xué)生實驗報告 系別 計算機(jī)科學(xué)與 工程學(xué)院 專業(yè) 班級 姓名 課程 名稱 課程 類型 學(xué)時數(shù) 2 實驗 名稱 實驗二、基于 TCP的服務(wù)器 / 客戶端編程 學(xué)號 日期 : 實驗?zāi)康?:1、掌握 Linux 下的 TCP客戶端基本原理和基本編程方法 實驗內(nèi)容: 1 、寫 Linux 下 TCP服務(wù)器套接字程序,程序運行時服務(wù)器等待客戶 的連接,一旦連接成功,則顯示客戶的 IP 地址、端口號,并向客戶端發(fā)送字 符串。 2、寫 Linux 下 TCP客戶端套接字程序,結(jié)合 TCP的服務(wù)器端程序,實現(xiàn)以下 功能: (1)、客戶根據(jù)用戶提供的 IP 地址連接到相應(yīng)的服務(wù)
2、器; (2)、服務(wù)器等待客戶的連接,一旦連接成功,則顯示客戶的 IP 地址、端口 號,并向客戶端發(fā)送字符串; (3)、客戶接收服務(wù)器發(fā)送的信息并顯示。 實驗步驟: 一、 TCP服務(wù)端程序設(shè)計 使用 TCP套接字編程可以實現(xiàn)基于 TCP/IP 協(xié)議的面向連接的通信,它分為服 務(wù)器端和客戶端兩部分,其主要實現(xiàn)過程如圖所示 圖 1.1 TCP 客戶/ 服務(wù)器的套接字函數(shù) 、 socket 函數(shù):為了執(zhí)行網(wǎng)絡(luò)輸入輸出,一個進(jìn)程必須做的第一件事就是調(diào)用socket 函 數(shù)獲得一個文件描述符。 #include int socket(int family,int type,int protocol); 返
3、回:非負(fù)描述字成功-1 失敗 第一個參數(shù)指明了協(xié)議簇,目前支持 5 種協(xié)議簇,最常用的有 AF_INET(IPv4 協(xié)議)和 AF_INET6(IPv6協(xié)議);第二個參數(shù)指明套接口類型, 有三種類型可選: SOCK_STREA字M節(jié)( 流套接口 ) 、SOCK_DGRA數(shù)M據(jù)( 報套接口 ) 和 SOCK RAW原(始套接口 ) ;如果套接口類型不是原始套接口,那么第三個參 數(shù)就為 0。 、 connect 函數(shù):當(dāng)用 socket 建立了套接口后,可以調(diào)用 connect 為這個 套接字指明遠(yuǎn)程端的地址; 如果是字節(jié)流套接口, connect 就使用三次握手建 立一個連接;如果是數(shù)據(jù)報套接口
4、, connect 僅指明遠(yuǎn)程端地址,而不向它發(fā) 送任何數(shù)據(jù)。 #include int connect(int sockfd, const struct sockaddr * addr, socklen_t addrlen); 返回: 0成功-1 失敗 第一個參數(shù)是 socket 函數(shù)返回的套接口描述字;第二和第三個參數(shù)分別 是一個指向套接口地址結(jié)構(gòu)的指針和該結(jié)構(gòu)的大小。 這些地址結(jié)構(gòu)的名字均已“ sockaddr_ ”開頭,并以對應(yīng)每個協(xié)議族的唯一后 綴結(jié)束。以 IPv4 套接口地址結(jié)構(gòu)為例,它以“ sockaddr_in ”命名,定義在頭 文件 ;以下是結(jié)構(gòu)體的內(nèi)容: struct in
5、_addr in_addr_t s_addr; ; struct sockaddr_in uint8_t sin_len; sa_family_t sin_family; in port t sin port; struct in_addr sin_addr; char sin_zero8; ; 、 bind 函數(shù):為套接口分配一個本地 IP 和協(xié)議端口,對于網(wǎng)際協(xié)議,協(xié)議 地址是 32位IPv4 地址或 128位IPv6地址與 16位的 TCP或UDP端口號的組 合;如指定端口為 0,調(diào)用 bind 時內(nèi)核將選擇一個臨時端口,如果指定一個 通配 IP 地址,則要等到建立連接后內(nèi)核才選擇一個本
6、地 IP 地址。 #include int bind(int sockfd, const struct sockaddr * server, socklen_t addrlen); 返回: 0成功-1 失敗 第一個參數(shù)是 socket 函數(shù)返回的套接口描述字;第二和第第三個參數(shù)分 別是一個指向特定于協(xié)議的地址結(jié)構(gòu)的指針和該地址結(jié)構(gòu)的長度。 、 listen 函數(shù): listen 函數(shù)僅被 TCP服務(wù)器調(diào)用,它的作用是將用 sock 創(chuàng)建的主動套接口轉(zhuǎn)換成被動套接口,并等待來自客戶端的連接請求。 #include int listen(int sockfd,int backlog); 返回: 0
7、成功-1 失敗 第一個參數(shù)是 socket 函數(shù)返回的套接口描述字;第二個參數(shù)規(guī)定了內(nèi)核 為此套接口排隊的最大連接個數(shù)。由于 listen 函數(shù)第二個參數(shù)的原因,內(nèi)核 要維護(hù)兩個隊列: 以完成連接隊列和未完成連接隊列。 未完成隊列中存放的是 TCP連接的三路握手為完成的連接, accept 函數(shù)是從以連接隊列中取連接返回 給進(jìn)程;當(dāng)以連接隊列為空時,進(jìn)程將進(jìn)入睡眠狀態(tài)。 、 accept 函數(shù): accept 函數(shù)由 TCP服務(wù)器調(diào)用,從已完成連接隊列頭返回 一個已完成連接,如果完成連接隊列為空,則進(jìn)程進(jìn)入睡眠狀態(tài)。 #include int accept(int listenfd, stru
8、ct sockaddr *client, socklen_t * addrlen); 回:非負(fù)描述字成功 -1 失敗 第一個參數(shù)是 socket 函數(shù)返回的套接口描述字;第二個和第三個參數(shù)分別是 一個指向連接方的套接口地址結(jié)構(gòu)和該地址結(jié)構(gòu)的長度; 該函數(shù)返回的是一個 全新的套接口描述字; 如果對客戶段的信息不感興趣, 可以將第二和第三個參 數(shù)置為空。 6、write 和 read 函數(shù):當(dāng)服務(wù)器和客戶端的連接建立起來后,就可以進(jìn)行數(shù) 據(jù)傳輸了,服務(wù)器和客戶端用各自的套接字描述符進(jìn)行讀 / 寫操作。因為套接 字描述符也是一種文件描述符,所以可以用文件讀 / 寫函數(shù) write() 和 read(
9、) 進(jìn)行接收和發(fā)送操作。 (1) write() 函數(shù)用于數(shù)據(jù)的發(fā)送。 #include int write(int sockfd, char *buf, int len); 回:非負(fù)成功 -1 失敗 參數(shù) sockfd 是套接字描述符, 對于服務(wù)器是 accept() 函數(shù)返回的已連接套接 字描述符,對于客戶端是調(diào)用 socket() 函數(shù)返回的套接字描述符;參數(shù) buf 是指向一個用于發(fā)送信息的數(shù)據(jù)緩沖區(qū); len 指明傳送數(shù)據(jù)緩沖區(qū)的大小。 (2) read() 函數(shù)用于數(shù)據(jù)的接收。 #include int read(int sockfd, char *buf, intlen); 回:
10、非負(fù)成功-1 失敗 參數(shù) sockfd 是套接字描述符, 對于服務(wù)器是 accept() 函數(shù)返回的已連接套接 字描述符,對于客戶端是調(diào)用 socket() 函數(shù)返回的套接字描述符;參數(shù) buf 是指向一個用于接收信息的數(shù)據(jù)緩沖區(qū); len 指明接收數(shù)據(jù)緩沖區(qū)的大小。 7、send 和 recv 函數(shù): TCP套接字提供了 send() 和 recv() 函數(shù),用來發(fā)送和 接收操作。這兩個函數(shù)與 write() 和 read() 函數(shù)很相似,只是多了一個附加 的參數(shù)。 (1) send() 函數(shù)用于數(shù)據(jù)的發(fā)送。 #include #include ssize t send(int sockfd
11、, const void *buf, size t len, int flags); 回:返回寫出的字節(jié)數(shù)成功 -1 失敗 前 3 個參數(shù)與 write() 相同,參數(shù) flags 是傳輸控制標(biāo)志。 (2) recv() 函數(shù)用于數(shù)據(jù)的發(fā)送。 #include #include ssize t recv(int sockfd, void *buf, size t len, int flags); 回:返回讀入的字節(jié)數(shù)成功 -1 失敗 前 3 個參數(shù)與 read() 相同,參數(shù) flags 是傳輸控制標(biāo)志。 實驗步驟 1、登陸進(jìn)入 ubuntu 操作系統(tǒng),新建一個文件,命名為 tcpserver
12、.c (為了方 便起見,可以進(jìn)入“home”,再進(jìn)入用戶目錄, 在用戶目錄下新建 tcpserver.c )。 2、在 tcpserver.c 中編寫服務(wù)器端程序代碼并保存。 3、在“終端”(“ Applications ”“附件”“終端”)中執(zhí)行命令進(jìn)入 tcpserver.c 所在目錄。 (pwd命令可以顯示當(dāng)前所在目錄; ls 命令可以顯示 當(dāng)前目錄下的文件和文件夾信息; cd. 命令可以進(jìn)入上一級目錄; cd 目錄名 命令可以進(jìn)入當(dāng)前所示的某個目錄。) 4、執(zhí)行命令 gcc o tcpserver tcpserver.c生成可執(zhí)行文件 tcpserver 。 5、執(zhí)行命令 ./ tcp
13、server ,觀察結(jié)果。 6、認(rèn)真分析源代碼,體會如何編寫一個 TCP服務(wù)器端程序。 參考程序 #include #include #include #include #include #include #include #include #definePORT 1234 #defineBACKLOG1 int main() int listenfd, connectfd; struct sockaddr_in server; struct sockaddr_in client; socklen_t addrlen; if(listenfd = socket(AF_INET, SOCK_ST
14、REAM0, ) = -1) sizeof(opt); perror(Creating socket failed.); exit(1); int opt =SO_REUSEADDR; setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR server.sin family=AF INET; eof(server) ten() */ server.sin_port=htons(PORT); server.sin_addr.s_addr= htonl (INADDR_ANY); if(bind(listenfd, = -1) perror(Binderror.)
15、; exit(1); (struct sockaddr *) exit(1); addrlen =sizeof(client); sockaddr*) if(connectfd = accept(listenfd,(struct exit(1); printf(Yougot a connection from cients ip is %s, prot is %dn,inet_ntoa(client.sin_addr),htons(client.sin_ port); send(connectfd,Welcometo my server.n,22,0); close(connectfd); c
16、lose(listenfd); return 0; 二、 TCP客戶端程序設(shè)計 實驗步驟 1、登陸進(jìn)入 ubuntu 操作系統(tǒng),新建一個文件,命名為 tcpclient.c (為了方 便起見,可以進(jìn)入“home”,再進(jìn)入用戶目錄, 在用戶目錄下新建 tcpclient.c ) 2、在 tcpclient.c 中編寫客戶端程序代碼并保存。將實驗一完成的 tcpserver.c 拷貝到與 tcpclient.c 同一目錄下。 3、在“終端”(“ Applications ”“附件”“終端”)中執(zhí)行命令進(jìn)入 tcpserver.c 和 tcpclient.c 所在目錄。 4、執(zhí)行命令 gcc o t
17、cpserver tcpserver.c生成可執(zhí)行文件 tcpserver 。 5、執(zhí)行命令 ./ tcpserver 。 6、再開一個“終端”,進(jìn)入 tcpserver.c 和 tcpclient.c 所在目錄,執(zhí)行命 令 gcc o tcpclient tcpclient.c 生成可執(zhí)行文件 tcpclient 。 7、執(zhí)行命令 ./ tcpclient 127.0.0.1。 8、觀察兩個“終端”出現(xiàn)的結(jié)果。 9、認(rèn)真分析源代碼,體會如何編寫一個 TCP客戶端程序。 參考程序 #include #include #include #include #include #include #in
18、clude #include #define PORT 1234 #defineMAXDATASIZE1 00 int main(int argc, char *argv) . int sockfd, num; char bufMAXDATASIZE; struct hostent *he; struct sockaddr_in server; if (argc!=2) printf(Usage:%s n,argv0); exit(1); if(he=gethostbyname(argv1)=NULL) printf(gethostbyname()errorn); exit(1); if(sockfd=socket(AF_INET,SOCK_STREAM0, )=-1) printf(socket()errorn); exit(1); bzero( server.sin_family=
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五版門診設(shè)備設(shè)施租賃與承包合同4篇
- 2025年度航空航天零部件加工與供應(yīng)分包合同3篇
- 二零二五年度離婚財產(chǎn)分割與子女撫養(yǎng)權(quán)分配合同4篇
- 2025年度美團(tuán)特色團(tuán)購合作合同范本細(xì)則4篇
- 2 24-全國護(hù)理專業(yè)教學(xué) 資源庫-1738309514230
- 診斷與改進(jìn)“應(yīng)知應(yīng)會”50問
- 2025年度特色培訓(xùn)學(xué)校股份合作發(fā)展合同3篇
- 2025年度校園春游活動團(tuán)隊旅游合同
- 二零二五年企業(yè)員工出差通訊費用報銷及標(biāo)準(zhǔn)合同3篇
- 2025年度個人信用借款合同隱私保護(hù)措施2篇
- 三年級數(shù)學(xué)(上)計算題專項練習(xí)附答案
- 中醫(yī)診療方案腎病科
- 2025年安慶港華燃?xì)庀薰菊衅腹ぷ魅藛T14人高頻重點提升(共500題)附帶答案詳解
- 人教版(2025新版)七年級下冊數(shù)學(xué)第七章 相交線與平行線 單元測試卷(含答案)
- 中藥飲片培訓(xùn)課件
- 醫(yī)院護(hù)理培訓(xùn)課件:《早產(chǎn)兒姿勢管理與擺位》
- 《論文的寫作技巧》課件
- 空氣自動站儀器運營維護(hù)項目操作說明以及簡單故障處理
- 2022年12月Python-一級等級考試真題(附答案-解析)
- T-CHSA 020-2023 上頜骨缺損手術(shù)功能修復(fù)重建的專家共識
- Hypermesh lsdyna轉(zhuǎn)動副連接課件完整版
評論
0/150
提交評論