Linux系統(tǒng)編程實驗七:網(wǎng)絡(luò)編程_第1頁
Linux系統(tǒng)編程實驗七:網(wǎng)絡(luò)編程_第2頁
Linux系統(tǒng)編程實驗七:網(wǎng)絡(luò)編程_第3頁
Linux系統(tǒng)編程實驗七:網(wǎng)絡(luò)編程_第4頁
Linux系統(tǒng)編程實驗七:網(wǎng)絡(luò)編程_第5頁
已閱讀5頁,還剩6頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、實驗七:網(wǎng)絡(luò)編程l 實驗?zāi)康模簩W(xué)會Linux的socket套接字網(wǎng)絡(luò)編程,熟悉使用TCP傳輸協(xié)議的網(wǎng)絡(luò)編程流程l 實驗要求:編寫使用TCP協(xié)議的服務(wù)器程序和客戶端程序,客戶端向服務(wù)器發(fā)送字符串,服務(wù)器打印收到的字符串l 實驗器材:軟件:安裝了Linux的vmware虛擬機硬件:PC機一臺l 實驗步驟:1、編寫服務(wù)器端代碼tcp_server.c#include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <netdb.h>

2、#include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #define portnumber 3333int main(int argc, char *argv) int sockfd,new_fd; struct sockaddr_in server_addr; struct sockaddr_in client_addr; int sin_size; int nbytes;char buffer1024;/*1、服務(wù)器創(chuàng)建sockfd描述符 */ if(sockfd=s

3、ocket(AF_INET,SOCK_STREAM,0)=-1)/ AF_INET:IPV4;SOCK_STREAM:TCP fprintf(stderr,"Socket error:%sna",strerror(errno); exit(1); /* 2、服務(wù)器端填充 sockaddr結(jié)構(gòu) */ bzero(&server_addr,sizeof(struct sockaddr_in); / 初始化,置0server_addr.sin_family=AF_INET; / Internetserver_addr.sin_addr.s_addr=htonl(INADD

4、R_ANY); / (將本機器上的long數(shù)據(jù)轉(zhuǎn)化為網(wǎng)絡(luò)上的long數(shù)據(jù))服務(wù)器程序能運行在任何ip的主機上/server_addr.sin_addr.s_addr=inet_addr("192.168.1.1"); /用于綁定到一個固定IP,inet_addr用于把數(shù)字加格式的ip轉(zhuǎn)化為整形ipserver_addr.sin_port=htons(portnumber); / (將本機器上的short數(shù)據(jù)轉(zhuǎn)化為網(wǎng)絡(luò)上的short數(shù)據(jù))端口號/* 3、綁定地址結(jié)構(gòu)體 */ if( bind(sockfd, &server_addr,sizeof(server_add

5、r)<0)printf(“bind error!”);exit(-1);/* 4、設(shè)置監(jiān)聽允許連接的最大客戶端數(shù) */ if( listen( sockfd, 0)<0)printf(“l(fā)isten error!”);exit(-1);while(1) /* 5、服務(wù)器阻塞,直到客戶程序建立連接 */ sin_size=sizeof(struct sockaddr_in); if(new_fd=accept(sockfd,& server_addr,&sin_size)<0)printf(“accept error!”);exit(-1); /連接成功后打印客

6、戶端IPfprintf(stderr,"Server get connection from %sn",inet_ntoa(client_addr.sin_addr); / 將網(wǎng)絡(luò)地址轉(zhuǎn)換成.字符串 /6、read()函數(shù)讀取客戶端發(fā)送的消息nbytes=read(new_fd,buffer,1024);buffernbytes='0'printf("Server received %sn",buffer);/* 這個通訊已經(jīng)結(jié)束 */ close(new_fd); /* 循環(huán)下一個 */ /* 結(jié)束通訊 */ close(sockfd)

7、; exit(0); /*完整程序*#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> #include<arpa/inet.h>/inet_ntoa()#include <unistd.h>/rea

8、d(),close()#define portnumber 3333int main(int argc, char *argv) int sockfd,new_fd; struct sockaddr_in server_addr; struct sockaddr_in client_addr; int sin_size; int nbytes;char buffer1024;/*1、服務(wù)器創(chuàng)建sockfd描述符 */ if(sockfd=socket(AF_INET,SOCK_STREAM,0)=-1) fprintf(stderr,"Socket error:%sna",

9、strerror(errno); exit(1); /* 2、服務(wù)器端填充 sockaddr結(jié)構(gòu) */ bzero(&server_addr,sizeof(struct sockaddr_in); server_addr.sin_family=AF_INET; server_addr.sin_addr.s_addr=htonl(INADDR_ANY);server_addr.sin_port=htons(portnumber); /* 3、綁定地址結(jié)構(gòu)體 */ if( bind(sockfd, (struct sockaddr *)(&server_addr),sizeof(s

10、truct sockaddr)<0)printf("bind error!");exit(-1);/* 4、設(shè)置監(jiān)聽允許連接的最大客戶端數(shù) */ if( listen( sockfd,5)<0)printf("listen error!");exit(-1);while(1) /* 5、服務(wù)器阻塞,直到客戶程序建立連接 */ sin_size=sizeof(struct sockaddr_in); if(new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),&sin_si

11、ze)<0)printf("accept error!");exit(-1); /連接成功后打印客戶端IP if(fork=0) /fork(),創(chuàng)建子進(jìn)程,多個進(jìn)程不需等候fprintf(stderr,"server get connection from %sn",inet_ntoa(client_addr.sin_addr); /6、read()函數(shù)讀取客戶端發(fā)送的消息nbytes=read(new_fd,buffer,1024);buffernbytes='0'printf("Server received %sn

12、",buffer);/* 這個通訊已經(jīng)結(jié)束 */ close(new_fd); else close(new_fd); /結(jié)束父進(jìn)程/* 循環(huán)下一個 */ /* 結(jié)束通訊 */ return 0; */2、編寫客戶端代碼tcp_client.c#include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <netdb.h> #include <sys/types.h> #include <neti

13、net/in.h> #include <sys/socket.h> #define portnumber 3333int main(int argc, char *argv) int sockfd; char buffer1024; struct sockaddr_in server_addr; struct hostent *host; /* 1、客戶程序開始建立 sockfd描述符 */ if(sockfd=socket(AF_INET,SOCK_STREAM,0)=-1) /AF_INET:Internet;SOCK_STREAM:TCP fprintf(stderr,

14、"Socket Error:%san",strerror(errno); exit(1); /* 2、客戶程序填充服務(wù)端的資料 */ bzero(&server_addr,sizeof(server_addr); / 初始化,置0server_addr.sin_family=AF_INET; / IPV4server_addr.sin_port=htons(portnumber); / (將本機器上的short數(shù)據(jù)轉(zhuǎn)化為網(wǎng)絡(luò)上的short數(shù)據(jù))端口號server_addr.sin_addr.s_addr=htonl(INADDR_ANY);/* 3、connect函

15、數(shù),客戶程序發(fā)起連接請求 */ if( connect( sockfd, &server_addr, sizeof(server_addr)<0)printf(“connet error!”);exit(-1);z/* 連接成功了 */ printf("Please input char:n");/* 等待終端輸入數(shù)據(jù) */fgets(buffer,1024,stdin); /4、write函數(shù)發(fā)送buffer數(shù)據(jù)write( sockfd,buffer,strlen(buffer);/* 結(jié)束通訊 */ close(sockfd); exit(0); /*完

16、整程序*#include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <netdb.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include<arpa/inet.h>/inet_ntoa()#include <unistd.h>/read(),close()#

17、define portnumber 3333int main(int argc, char *argv) int sockfd; char buffer1024; struct sockaddr_in server_addr; struct hostent *host; /* 1、客戶程序開始建立 sockfd描述符 */ if(sockfd=socket(AF_INET,SOCK_STREAM,0)=-1) /AF_INET:Internet;SOCK_STREAM:TCP fprintf(stderr,"Socket Error:%san",strerror(errno

18、); exit(1); /* 2、客戶程序填充服務(wù)端的資料 */ bzero(&server_addr,sizeof(server_addr); / 初始化,置0server_addr.sin_family=AF_INET; / IPV4server_addr.sin_port=htons(portnumber); / (將本機器上的short數(shù)據(jù)轉(zhuǎn)化為網(wǎng)絡(luò)上的short數(shù)據(jù))端口號server_addr.sin_addr.s_addr=htonl(INADDR_ANY);/* 3、connect函數(shù),客戶程序發(fā)起連接請求 */ if(connect( sockfd, (struct

19、sockaddr *)(&server_addr), sizeof(server_addr)<0)printf("connet error!");exit(-1);/* 連接成功了 */ printf("Please input char:n");/* 等待終端輸入數(shù)據(jù) */fgets(buffer,1024,stdin); /4、write函數(shù)發(fā)送buffer數(shù)據(jù)write( sockfd,buffer,strlen(buffer);/* 結(jié)束通訊 */ close(sockfd); exit(0); return 0;*/3、編譯并運行

20、應(yīng)用程序先運行服務(wù)器程序tcp_server,然后在另一個終端中運行客戶端程序tcp_client。從運行情況可以看出,在沒有客戶端連接上來時服務(wù)器程序阻塞在accept函數(shù)上,等待連接,當(dāng)有客戶端程序連接上來時,阻塞在read函數(shù)上,等待讀取消息。客戶端發(fā)送一條消息后結(jié)束,服務(wù)器讀取消息并打印出來,繼續(xù)等待新的連接l 上機報告要求:上面的TCP服務(wù)器每次只能處理一次客戶端請求,嘗試將他改寫成并發(fā)TCP服務(wù)器,即可以處理多個客戶端請求,測試成功后將代碼寫入實驗報告。/*#include<sys/socket.h>int scoket(int domain,int type,int

21、protocol)socket函數(shù)對應(yīng)于普通文件的打開操作。普通文件的打開操作返回一個文件描述字,而socket()用于創(chuàng)建一個socket描述符(socket descriptor),它唯一標(biāo)識一個socket。這個socket描述字跟文件描述字一樣,后續(xù)的操作都有用到它,把它作為參數(shù),通過它來進(jìn)行一些讀寫操作。正如可以給fopen的傳入不同參數(shù)值,以打開不同的文件。創(chuàng)建socket的時候,也可以指定不同的參數(shù)創(chuàng)建不同的socket描述符,socket函數(shù)的三個參數(shù)分別為:domain:即協(xié)議域,又稱為協(xié)議族(family)。常用的協(xié)議族有,AF_INET (IPv4 英特網(wǎng)域)、AF_IN

22、ET6 (IPv6英特網(wǎng)域)、AF_LOCAL(或稱AF_UNIX,Unix域socket)、AF_ROUTE等等。協(xié)議族決定了socket的地址類型,在通信中必須采用對應(yīng)的地址,如AF_INET決定了要用ipv4地址(32位的)與端口號(16位的)的組合、AF_UNIX決定了要用一個絕對路徑名作為地址。type:指定socket類型。常用的socket類型有,SOCK_STREAM(流式套接字 TCP)、SOCK_DGRAM(數(shù)據(jù)報套接字 UDP)、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等等(socket的類型有哪些?)。protocol:故名思意,就是指定協(xié)

23、議。(按給定的域和套接字類型選擇默認(rèn)協(xié)議,通常為0)常用的協(xié)議有,IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等,它們分別對應(yīng)TCP傳輸協(xié)議、UDP傳輸協(xié)議、STCP傳輸協(xié)議、TIPC傳輸協(xié)議當(dāng)我們調(diào)用socket創(chuàng)建一個socket時,返回的socket描述字它存在于協(xié)議族(address family,AF_XXX)空間中,但沒有一個具體的地址。如果想要給它賦值一個地址,就必須調(diào)用bind()函數(shù),否則就當(dāng)調(diào)用connect()、listen()時系統(tǒng)會自動隨機分配一個端口。字節(jié)序轉(zhuǎn)換不同類型的CPU對變量的字節(jié)存儲順序可能不同:有的系

24、統(tǒng)是大端字節(jié)序,即高位在低地址,即低位在高地址,而有的系統(tǒng)如x86是小端字節(jié)序,即低位在低地址,高位在高地址,而網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)順序是一定要統(tǒng)一的,所有當(dāng)內(nèi)部字節(jié)存儲順序和網(wǎng)絡(luò)字節(jié)序(大端字節(jié)序)不同時,就一定要進(jìn)行轉(zhuǎn)換unsigned long htonl(unsigned long hostlong);unsigned short htons(unsigned short hostshort);unsigned long ntohl(unsigned long netlong);unsigned short ntohs(unsigned short netshort);htonl()函數(shù)是將

25、32位無符號長整形數(shù)據(jù)從主機字節(jié)序轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)序返回值:htonl()返回一個網(wǎng)絡(luò)字節(jié)順序的值。htons()函數(shù)是將16位無符號短整形數(shù)據(jù)從主機字節(jié)序轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)序返回值:htons()返回一個網(wǎng)絡(luò)字節(jié)順序的值。htonl()/htons()函數(shù)是將32/16位整形數(shù)據(jù)從網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)換為主機字節(jié)序通用地址格式struct sockaddr unsigned short sa_family;  /* 地址族, AF_xxx */char sa_data14;  /* 14字節(jié)的協(xié)議地址*/;sa_family:協(xié)議族,采用“AF_xxx”形式,如AF_INET(IP協(xié)議

26、族)(domain)sa_data:1包含了一些遠(yuǎn)程電腦的地址、端口和套接字的數(shù)目,它里面的數(shù)據(jù)是夾雜在一起的struct sockaddr_in short int sin_family; /* 地址族 */unsigned short int sin_port; /* 端口號 */struct in_addr sin_addr; /* Internet地址 */unsigned char sin_zero8; /* 與struct sockaddr一樣的長度 */;IP地址通常由數(shù)字加點(192.168.0.1)的形式表示,而struct in_addr中使用的IP地址是由32位的整數(shù)表示

27、的,為了轉(zhuǎn)換我們可以使用下面兩個函數(shù):in_addr_t inet_addr(const char* strptr); 將一個點分十進(jìn)制的IP轉(zhuǎn)換成一個長整數(shù)型數(shù)(u_long類型)char *inet_ntoa(struct in_addr in)函數(shù)里面a代表ascii,n代表networkinet_aton是將a.b.c.d形式的IP轉(zhuǎn)換為32位的IP,存儲在inp指針里面,inet_ntoa是將32位IP轉(zhuǎn)換為a.b.c.d的格式struct in_addr unsigned long s_addr;#include<sys/socket.h>int bind(int so

28、ckfd, const struct sockaddr *addr, socklen_t addrlen);函數(shù)的三個參數(shù)分別為:sockfd:即socket描述字,它是通過socket()函數(shù)創(chuàng)建了,唯一標(biāo)識一個socket。bind()函數(shù)就是將給這個描述字綁定一個名字。addr:一個const struct sockaddr *指針,指向要綁定給sockfd的協(xié)議地址。這個地址結(jié)構(gòu)根據(jù)地址創(chuàng)建socket時的地址協(xié)議族的不同而不同。 addrlen:對應(yīng)的是地址的長度。(通常設(shè)為scokaddr結(jié)構(gòu)的長度)返回值:成功返回0,否則返回-1如果作為一個服務(wù)器,

29、在調(diào)用socket()、bind()之后就會調(diào)用listen()來監(jiān)聽這個socket,如果客戶端這時調(diào)用connect()發(fā)出連接請求,服務(wù)器端就會接收到這個請求。#include<sys/socket.h>int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);sockfd:為客戶端的socket描述字,addr:為服務(wù)器的socket地址(為指向sockaddr結(jié)構(gòu)的指針),addrlen:為socket地址的長度。客戶端通過調(diào)用connect函數(shù)來建立與TCP服務(wù)器的連接。返回值:0成功,-1錯誤#include<sys/socket.h>int listen(int sockfd, int backlog);sockfd,:為要監(jiān)聽的socket描述字,backlog:為相應(yīng)socket可以排隊的最大連接個數(shù)。(系統(tǒng)默認(rèn)值為20,0表示無限制)socket()函數(shù)創(chuàng)建的socket

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論