




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、,網(wǎng)絡(luò)編程技術(shù),設(shè)計、制作:譚獻海 Email:,socket(套接字),Socket API ARPA UC Berkeley BSD unix /Berkeley unix De facto standard Example Server Client,一個本地主機建立或擁有的應(yīng)用程序, 操作系統(tǒng)控制下的,與其它(遠程)應(yīng)用進程之間發(fā)送和接收數(shù)據(jù)的接口,通信協(xié)議應(yīng)用程序接口(APIs)-依賴于操作系統(tǒng)和編程語言 UNIX: Berkeley Sockets (C語言) System V Transport Layer Interface (TLI) (C語言) WINDOWS:WINSOC
2、K,客戶端,socket 是進行程序間通訊(IPC)的 BSD 方法。 客戶將插頭插入一個服務(wù)器端口 建立一個雙向的連接管道,服務(wù)器,插口(port),socket的抽象表示,一些Socket編程的概念,流(Stream) 連接(Connection) 阻塞(Block)、非阻塞(Non-block) 同步(Synchronous)、異步(asynchronous) IP地址 (IP Address) 字節(jié)順序(Bytes Order) 帶外數(shù)據(jù)(Outband Data),需要用到的頭文件,數(shù)據(jù)類型:#include 函數(shù)定義:#include ,Berkeley Socket 常用函數(shù)列表
3、,網(wǎng)絡(luò)連接函數(shù) 獲取/設(shè)置socket的參數(shù)或信息 轉(zhuǎn)換函數(shù),網(wǎng)絡(luò)連接函數(shù),socket bind connect listen accept select recv, recvfrom send, sendto close, shutdown,獲取/設(shè)置socket的參數(shù)或信息,gethostbyaddr, gethostbyname gethostname getpeername getprotobyname, getprotobynumber getservbyname, getservbyport getsockname getsockopt, setsockopt ioctl,轉(zhuǎn)換函
4、數(shù),IP地址轉(zhuǎn)換 inet_addr() inet_ntoa() 字節(jié)順序轉(zhuǎn)換 htons()-Host to Network Short htonl()-Host to Network Long ntohs()-Network to Host Short ntohl()-Network to Host Long,socket address structures for Internet,XNS and Unix families,Struct sockaddr_in Struct sockaddr_us,struct sockaddr_un,socket address,The famil
5、y is one of AF_UNIXUnix internal protocols AF_INETInternet protocols AF_NSXerox NS protocols AF_IMPLINKIMP link layer 其中,AF_ 代表“address family” Socket地址的數(shù)據(jù)部分根據(jù)不同的地址類型來解釋,常見的地址類型是internet、XNS和UNIX。 對于使用最多的INTERNET簇,其網(wǎng)絡(luò)地址主要包括兩大部分:端口號、IP地址,它的地址結(jié)構(gòu)在中定義,數(shù)據(jù)結(jié)構(gòu):sockaddr_in,Internet地址 struct sockaddr_in short
6、 int sin_family; /* Address family */ unsigned short int sin_port; /* Port number */ /* 16-bit port number , network byte ordered */ struct in_addr sin_addr; /* Internet address */ /* 32-bit netid/hosted (IP)地址, network byte ordered */ unsigned char sin_zero 8; /* unused */ ; 該結(jié)構(gòu)與sockaddr兼容,供用戶填入?yún)?shù),
7、程序中實際只填寫sockaddr_in結(jié)構(gòu),struct sockaddr_in my_addr; my_addr.sin_family = AF_INET; my_addr.sin_port = htons(3490); /* short, NBO*/ my_addr.sin_addr.s_addr = inet_addr(0); bzero( 注意:sin_addr.s_addr填本機IP地址,如果此項填I(lǐng)NADDR_ANY時,表示自動取本機IP填入該項(僅用于Server),創(chuàng)建一個socket Socket描述符與Linux中的文件描述符類似,也是一個int型的變
8、量 函數(shù)調(diào)用: int socket(int family, int type, int protocol); 函數(shù)返回Socket描述符,返回-1表示出錯 family參數(shù)一般取AF_INET, protocol參數(shù)一般取0 應(yīng)用示例: TCP:sockfd = socket(AF_INET,SOCK_STREAM,0); UDP:sockfd =socket(AF_INET, SOCK_DGRAM,0);,socket()調(diào)用,“協(xié)議” 與“family” 及“type”域的可能組合,在服務(wù)器上運行,給socket指定一個眾所周知的 (well-known) 端口地址 int bind (
9、int sockfd, const struct sockaddr *myaddr, socklen_t addrlen),bind() 調(diào)用,如果調(diào)用成功,則返回值為0,如果調(diào)用失敗返回值為-1,并設(shè)定相應(yīng)的錯誤代碼errno。最常見的錯誤是該端口已經(jīng)被其他程序綁定。 需要注意的一點:在Linux系統(tǒng)中,1024以下的端口(即眾所周知的端口)只有擁有root權(quán)限的程序才能綁定,bind() 調(diào)用,Bind()系統(tǒng)調(diào)用主要用處: A)服務(wù)員向系統(tǒng)注冊它的眾所周知的地址,它告訴系統(tǒng):“這是我的地址(服務(wù)),所有以這個地址接收的報文都交給我,由我來服務(wù)?!泵嫦蜻B接和無連接的服務(wù)員在接受顧客的請求之
10、前都必須做這一步。 B)顧客可為它自己注冊一個特定的地址,以便通信的對方(服務(wù)員)可以用這個有效的地址送回響應(yīng),這就像在信封上要寫明回信地址的道理一樣。,開始監(jiān)聽已經(jīng)綁定的端口 需要在此前調(diào)用bind()函數(shù),否則由系統(tǒng)指定一個隨機的端口 int listen(int sockfd, int queue_length); 接收隊列 一個新的Client的連接請求先被放在接收隊列中,等待Server程序調(diào)用accept函數(shù)接受該連接請求 queue_length用于指定接收隊列的長度,也就是在Server程序調(diào)用accept函數(shù)之前最大允許進入的連接請求數(shù),多余的連接請求將被拒絕,典型取值為5,
11、listen() 調(diào)用,操作系統(tǒng),Web 服務(wù)器,服務(wù)器初始化,建立與服務(wù)器的連接 int connect (int sockfd, const struct sockaddr *servaddr, socklen_t addrlen) servaddr是事先填寫好的結(jié)構(gòu),用于指定所要連接的服務(wù)器的地址(Server的IP地址和端口號)。,connect() 調(diào)用,OS,1. socket(),Web 服務(wù)器,2. bind(80),3. listen(),80,Listen queue,客戶,connect(),Request from (IP, port),建立與服務(wù)器的連接,操作系統(tǒng),W
12、eb 服務(wù)器,80,Listen 隊列,客戶1,客戶3,客戶2,客戶請求在listen隊列中獲取先進先出服務(wù)(排隊),服務(wù)器忙,accept(),accept()函數(shù)用于響應(yīng)客戶的連接請求,建立與客戶端的連接 產(chǎn)生一個新的socket描述符來描述該連接 這個連接用來與發(fā)起該連接請求的Client交換信息 int accept(int sockfd,struct sockaddr *addr,int addrlen); addr將在函數(shù)調(diào)用后被填入連接對方(客戶端)的地址信息,如對方的IP、端口等。 accept缺省是阻塞函數(shù),如果隊列中沒有連接請求等待,那么就會使調(diào)用方阻塞,直到有一個連接請求
13、到達。,操作系統(tǒng),Web 服務(wù)器,80,Listen 隊列,客戶 1,客戶3,客戶2,客戶請求在listen隊列中奪取先進先出服務(wù),accept(),已連接的 socket,accept() 調(diào)用,accept()的使用,include #include #include #define MYPORT 80 /* the port users will be connecting to */ #define BACKLOG 5 /* how many pending connections queue will hold */ main() int sockfd, new_fd; /* lis
14、ten on sock_fd, new connection on new_fd */ struct sockaddr_in my_addr; /* my address information */ struct sockaddr_in their_addr; /* connectors address information */ int sin_size; sockfd = socket(AF_INET, SOCK_STREAM, 0); /* do some error checking! */,accept(),my_addr.sin_family = AF_INET; /* hos
15、t byte order */ my_addr.sin_port = htons(MYPORT); /* short, network byte order */ my_addr.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */ bzero( ,服務(wù)器都可工作在兩種不同的方式: 循環(huán)方式(iterative mode)在計算機中一次只運行一個服務(wù)器進程。當(dāng)有多個客戶進程請求服務(wù)時,服務(wù)器進程就按請求的先后順序依次做出響應(yīng)。 并發(fā)方式(concurrent)在計算機中同時運行多個服務(wù)器進程,每一個服務(wù)器進程對某個特定的客戶進程做出響
16、應(yīng)。,服務(wù)器的兩種工作方式,循環(huán)型服務(wù)員代碼,int sockfd,newsockfd; if (sockfd=socket()0) err_sys(“socket error”); if (bind(sockfd,)0) err_sys(“bind error”); if (listen(sockfd,5)0) err_sys(“l(fā)isten error”); for ( ; ; ) newsockfd=accept(sockfd,);/* blocks */ if (newsockfd0) err_sys(“accept error”); doit(newsockfd);/* proces
17、s the request */ close(newsockfd); ,并發(fā)型服務(wù)員代碼,int sockfd,newsockfd; if (sockfd=socket()0) err_sys(“socket error”); if (bind(sockfd,)0) err_sys(“bind error”); if (listen(sockfd,5)0) err_sys(“l(fā)isten error”); for ( ; ; ) newsockfd=accept(sockfd,);/* blocks */ if (newsockfd0) err_sys(“accept error”); if
18、(fork()=0)/* child */ close(sockfd); doit(newsockfd);/* process the request */ exit(0); close(newsockfd);/* parent */ ,發(fā)送和接收,在完成了上述的初始化工作后,就可以開始傳輸數(shù)據(jù)了。 面向連接的發(fā)送和接收 : send() and recv() 無連接協(xié)議的發(fā)送和接收:sendto()和recvfrom(),recv,用于TCP協(xié)議中接收信息 int recv(int sockfd, void *buf, int len, int flags); Buf:指向容納接收信息的緩沖
19、區(qū)的指針 Len:接收緩沖區(qū)的大小 Flags:接收標志(其含義將在后面介紹) 函數(shù)返回實際接收到的字節(jié)數(shù),返回-1表示出錯 recv缺省是阻塞函數(shù),直到接收到信息或出錯才返回,send,用于TCP協(xié)議中發(fā)送信息 int send(int sockfd, const void *msg, int len, int flags); Msg:指向待發(fā)送信息的指針 Len:待發(fā)送的字節(jié)數(shù) Flags:發(fā)送標志(其含義將在后面介紹) 函數(shù)返回已發(fā)送的字節(jié)數(shù),返回-1表示出錯 send缺省是阻塞函數(shù),直到發(fā)送完畢或出錯 注意:如果函數(shù)返回值與參數(shù)len不相等,則剩余的未發(fā)送信息需要再次發(fā)送,recvfr
20、om,用于UDP協(xié)議中接收信息 int recvfrom(int sockfd,void *buf,int len,unsigned int flags struct sockaddr *from, int *fromlen); Buf:指向容納接收信息的緩沖區(qū)的指針 Len:緩沖區(qū)的大小 Flags:接收標志(其含義將在后面介紹) From:指明接收數(shù)據(jù)的來源 Fromlen:地址長度 函數(shù)返回實際接收的字節(jié)數(shù),返回-1表示出錯 recvfrom是阻塞函數(shù),直到接收到信息或出錯,sendto,用于UDP協(xié)議中發(fā)送信息 int sendto(int sockfd, const void *ms
21、g, int len, unsigned int flags, const struct sockaddr *to, int tolen); Buf:指向容納發(fā)送報文的緩沖區(qū)的指針 Len:緩沖區(qū)的大小 Flags:發(fā)送標志 To:指明發(fā)送數(shù)據(jù)的目的地 tolen :地址長度 函數(shù)返回已發(fā)送的字節(jié)數(shù),返回-1表示出錯 sendto缺省是阻塞函數(shù),直到發(fā)送完畢或出錯 注意:如果函數(shù)返回值與參數(shù)len不相等,則剩余的未發(fā)送信息需要再次發(fā)送,send, sendto, recv, recvfrom函數(shù)調(diào)用的參數(shù):flags,Flags一般情況下設(shè)置為0。但可以選擇下列設(shè)置 MSG_DONTROUTE
22、 對send, sendto有效 表示不使用路由(一般不使用) MSG_PEEK 對recv, recvfrom有效 表示讀出網(wǎng)絡(luò)數(shù)據(jù)后不清除已讀的數(shù)據(jù) MSG_OOB 對發(fā)送接收都有效 表示讀/寫帶外數(shù)據(jù)(out-of-band data),close,關(guān)閉特定的socket連接 調(diào)用函數(shù):int close(int sockfd); 關(guān)閉連接將中斷對該socket的讀寫操作。 關(guān)閉用于listen()函數(shù)的socket將禁止其他Client的連接請求,shutdown,Shutdown()函數(shù)可以單方面的中斷連接,即禁止某個方向的信息傳遞。 函數(shù)調(diào)用 int shutdown(int so
23、ckfd, int how); 參數(shù)how: 0 - 禁止接收信息 1 - 禁止發(fā)送信息 2 - 接收和發(fā)送都被禁止,與close()函數(shù)效果相同 返回0表示調(diào)用成功,返回-1表示出錯,select,應(yīng)用于多路同步I/O模式,實現(xiàn)非阻塞的同步I/O int select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); numfds是要多路選擇的socket的最大值 其中readfds, writefds, exceptfds都是socket事件集合,分別代表有
24、數(shù)據(jù)可讀、有數(shù)據(jù)要寫、發(fā)生異常的socket集合。 timeout是select的時間限制 返回值:在socket集合中準備好的socket個數(shù),socket集合,集合變量類型:fd_set 集合變量運算宏: FD_ZERO(*set)清空socket集合 FD_SET(s, *set)將s加入socket集合 FD_CLR(s, *set)從socket集合去掉s FD_ISSET(s, *set)判斷s是否在socket集合中 常數(shù)FD_SETSIZE:集合元素的最多個數(shù),Select應(yīng)用舉例,fd_set rset;/* 可讀的socket集合 */ FD_ZERO( /* maxfd是
25、已知的最大的socket */ /* 只考慮數(shù)據(jù)可讀事件 */ if (FD_ISSET(sockfd, - 其中,參數(shù)peer是一個指向struct sockaddr或者struct sockaddr_in的指針。 如果執(zhí)行成功,我們就得到了對方的地址和端口號,然后用inet_ntoa()和gethostbyaddr()來得到對方更多的信息。,其他基本的系統(tǒng)調(diào)用,getsockname 該系統(tǒng)調(diào)用返回和一個管套相聯(lián)系的本地名字 - #include #include int getsockname(int sockfd, struct sockaddr *addr, int *addrlen
26、); - addr用來存放返回的本地地址;addrlen存放的是返回的地址的長度。,其他基本的系統(tǒng)調(diào)用,系統(tǒng)調(diào)用 gethostname() - - #include int gethostname(char *hostname, size_t size); - - hostname是一個存放主機名字(域名)的字符數(shù)組 返回的hostname可以作為gethostbyname()的參數(shù),調(diào)用該系統(tǒng)調(diào)用,這樣又可以得到自己的IP地址了。,其他基本的系統(tǒng)調(diào)用,字節(jié)排序 在字節(jié)順序不一致時可以用下列的4中函數(shù)來進行轉(zhuǎn)換。 #include #include u_long htonl(u_long h
27、ostlong);/* 主機網(wǎng)絡(luò)轉(zhuǎn)換,長整數(shù) */ u_short htons(u_long hostlong);/* 主機網(wǎng)絡(luò)轉(zhuǎn)換,短整數(shù) */ u_long ntohl(u_long hostlong);/* 網(wǎng)絡(luò)主機轉(zhuǎn)換,長整數(shù) */ u_chort ntohs(u_long hostlong);/* 網(wǎng)絡(luò)主機轉(zhuǎn)換,短整數(shù) */ 這些函數(shù)是為internet協(xié)議集而設(shè)計的,XNS協(xié)議集采用的字節(jié)順序與internet相同,故可以借用。值得注意的是,這里的長整數(shù)為32位,短整數(shù)為16位。,其他基本的系統(tǒng)調(diào)用,字節(jié)操作 Bcopy(char *src,char *dest,int nbyte
28、s); 字符串拷貝 Bzero(char *dest,int nbytes); 把指定數(shù)量的空字節(jié)寫入指定的目的地址。 Int bcmp(char *ptr1,char *ptr2,int nbytes); 對任意兩個字符串進行比較。 返回值(與標準I/O函數(shù)strcmp的返回值不同): 0-相同 非零-不相同。,其他基本的系統(tǒng)調(diào)用,IP地址格式轉(zhuǎn)換 下列兩個函數(shù)用于在Internet的用小數(shù)點分隔的十進制IP地址與32比特IP地址之間進行轉(zhuǎn)換。 #include #include #include unsigned long inet_addr (const char *cp); inet_addr將一個點分十進制IP地址字符串轉(zhuǎn)換成32位數(shù)字表示的IP地址 char* inet_ntoa (struct in_addr in); inet_ntoa將一個32位數(shù)字表示的IP地址轉(zhuǎn)換成點分十進制IP地址字符串,其他基本的系統(tǒng)調(diào)
溫馨提示
- 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)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 農(nóng)機大院農(nóng)機管理辦法
- 近現(xiàn)代文學(xué)批評主體與客體:期刊書評的媒介作用
- “新質(zhì)生產(chǎn)力”引領(lǐng)下的“檔案文化產(chǎn)業(yè)”發(fā)展新模式、新趨勢與新路徑探索
- 江西補貼資金管理辦法
- 施工現(xiàn)場監(jiān)督與質(zhì)量控制
- 單位消防安全管理人員職責(zé)
- 安全環(huán)保警示教育心得體會
- 2025熱電車間鍋爐重大危險源安全檢查表
- 安全生產(chǎn)責(zé)任制是一項
- 小型水庫大壩安全管理應(yīng)急預(yù)案
- 國家開放大學(xué)電大本科《婦產(chǎn)科學(xué)與兒科護理學(xué)(本)》期末題庫及答案
- 井下變電所停送電操作規(guī)程
- 我的妹妹高中 我的妹妹初中800字(三篇)
- -衛(wèi)生資格-副高-內(nèi)科護理-副高-章節(jié)練習(xí)-護理學(xué)總論-醫(yī)院感染護理(案例分析題)(共6題)
- 中國古代文化常識(上)
- 禮品禮金登記表
- 【新】2019-2020成都市石室中學(xué)北湖校區(qū)初升高自主招生數(shù)學(xué)【4套】模擬試卷【含解析】
- 《文明禮貌我最棒》班會課件
- 意外受傷賠償協(xié)議書的格式
- PE管閉水試驗表
- 山東省教師職稱改革實施方案
評論
0/150
提交評論