版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
Socket網(wǎng)絡(luò)開發(fā)目標(biāo)什么是套接字?Internet套接字的兩種類型網(wǎng)絡(luò)理論IP地址和如何處理它們使用Socket開發(fā)網(wǎng)絡(luò)程序什么是socket?所謂socket通常也稱作“套接字”,用于描述IP地址和端口,是一個通信鏈的句柄。應(yīng)用程序通常通過“套接字”向網(wǎng)絡(luò)發(fā)出請求或者應(yīng)答網(wǎng)絡(luò)請求。生成套接字,主要有3個參數(shù):通信的目的IP地址、使用的傳輸層協(xié)議(TCP或UDP)和使用的端口號。Socket原意是“插座”。通過將這3個參數(shù)結(jié)合起來,與一個“插座”Socket綁定,應(yīng)用層就可以和傳輸層通過套接字接口,區(qū)分來自不同應(yīng)用程序進程或網(wǎng)絡(luò)連接的通信,實現(xiàn)數(shù)據(jù)傳輸?shù)牟l(fā)服務(wù)。Socket可以看成在兩個程序進行通訊連接中的一個端點,一個程序?qū)⒁欢涡畔懭隨ocket中,該Socket將這段信息發(fā)送給另外一個Socket中,使這段信息能傳送到其他程序中。
套接字的兩種類型一種是“StreamSockets”(流格式),另外一種是“DatagramSockets”(數(shù)據(jù)包格式)。我們以后談到它們的時候也會用到SOCK_STREAM和SOCK_DGRAM。數(shù)據(jù)報套接字有時也叫“無連接套接字”(如果你確實要連接的時候可以用connect()。)流式套接字是可靠的雙向通訊的數(shù)據(jù)流。如果你向套接字按順序輸出“1,2”,那么它們將按順序“1,2”到達另一邊。它們是無錯誤的傳遞的,除非自己的控制錯誤。例如:telnet、及ftp等都是使用流格式,這是因為它使用了“傳輸控制協(xié)議(TheTransmissionControlProtocol)”。流式套接字可以達到高質(zhì)量的數(shù)據(jù)傳輸。網(wǎng)絡(luò)理論網(wǎng)絡(luò)分層模型(LayeredNetworkModel)?,F(xiàn)在列出整個層次模型。如果你要參加網(wǎng)絡(luò)考試,可一定要記?。?/p>
應(yīng)用層(Application)
表示層(Presentation)
會話層(Session)
傳輸層(Transport)
網(wǎng)絡(luò)層(Network)
數(shù)據(jù)鏈路層(DataLink)
物理層(Physical)
物理層是硬件(串口,以太網(wǎng)等等)。應(yīng)用層是和硬件層相隔最遠(yuǎn)的--它是用戶和網(wǎng)絡(luò)交互的地方。
這個模型如此通用,如果你想,你可以把它作為修車指南。把它對應(yīng)到Unix,結(jié)果是:
應(yīng)用層(ApplicationLayer)(telnet,ftp,等等)
傳輸層(Host-to-HostTransportLayer)(TCP,UDP)
Internet層(InternetLayer)(IP和路由)
網(wǎng)絡(luò)訪問層(NetworkAccessLayer)
(網(wǎng)絡(luò)層,數(shù)據(jù)鏈路層和物理層)
網(wǎng)絡(luò)數(shù)據(jù)排列有兩種字節(jié)排列順序:重要的字節(jié)(有時叫“octet”,即八位位組)在前面,或者不重要的字節(jié)在前面。前一種叫“網(wǎng)絡(luò)字節(jié)順序(NetworkByteOrder)”。有些機器在內(nèi)部是按照這個順序儲存數(shù)據(jù),而另外一些則不然。當(dāng)我說某數(shù)據(jù)必須按照NBO順序,那么你要調(diào)用函數(shù)(例如htons())來將它從本機字節(jié)順序(HostByteOrder)轉(zhuǎn)換過來。如果我沒有提到NBO,那么就讓它保持本機字節(jié)順序。
Socket數(shù)據(jù)類型socket描述符:僅僅是一個常見的int。套接字地址信息structsockaddr{
unsignedshortsa_family;/*地址家族,AF_xxx*/
charsa_data[14];/*14字節(jié)協(xié)議地址*/
};
sa_family能夠是各種各樣的類型,但是在這篇文章中都是"AF_INET"。sa_data包含套接字中的目標(biāo)地址和端口信息。為了處理structsockaddr,程序員創(chuàng)造了一個并列的結(jié)構(gòu):structsockaddr_in("in"代表"Internet"。)
structsockaddr_in{
shortintsin_family;/*通信類型*/
unsignedshortintsin_port;/*端口*/
structin_addrsin_addr;/*Internet地址*/
unsignedcharsin_zero[8];/*與sockaddr結(jié)構(gòu)的長度相同*/};
IP地址如何處理假設(shè)你已經(jīng)有了一個sockaddr_in結(jié)構(gòu)體ina,你有一個IP地址"0"要儲存在其中,你就要用到函數(shù)inet_addr(),將IP地址從點數(shù)格式轉(zhuǎn)換成無符號長整型。使用方法如下:
ina.sin_addr.s_addr=inet_addr("");
好了,現(xiàn)在你可以將IP地址轉(zhuǎn)換成長整型了。有沒有其相反的方法呢?它可以將一個in_addr結(jié)構(gòu)體輸出成點數(shù)格式?這樣的話,你就要用到函數(shù)inet_ntoa()("ntoa"的含義是"networktoascii"),就像這樣:
printf("%s",inet_ntoa(ina.sin_addr));
socket()函數(shù)Windows包含文件:
#include<WinSock2.h>
intsocket(intdomain,inttype,intprotocol);domain應(yīng)該設(shè)置成“AF_INET”,就象上面的數(shù)據(jù)結(jié)構(gòu)structsockaddr_in中一樣。參數(shù)type告訴內(nèi)核是SOCK_STREAM類型還是SOCK_DGRAM類型。把protocol設(shè)置為“0”。(注意:有很多種domain、type,我不一一列出了,請看socket()的幫助。socket()只是返回你以后在系統(tǒng)調(diào)用種可能用到的socket描述符,或者在錯誤的時候返回-1。使用WSAGetLastError()可以查看錯誤原因。bind()函數(shù)一旦你有一個套接字,你可能要將套接字和機器上的一定的端口關(guān)聯(lián)起來。intbind(intsockfd,structsockaddr*my_addr,intaddrlen);sockfd是調(diào)用socket返回的文件描述符。my_addr是指向數(shù)據(jù)結(jié)構(gòu)structsockaddr的指針,它保存你的地址(即端口和IP地址)信息。my_addr.sin_port是網(wǎng)絡(luò)字節(jié)順序,addrlen設(shè)置為sizeof(structsockaddr)。在處理自己的IP地址和/或端口的時候,有些工作是可以自動處理的。
my_addr.sin_port=0;/*隨機選擇一個沒有使用的端口*/
my_addr.sin_addr.s_addr=INADDR_ANY;/*使用自己的IP地址*/
通過將0賦給my_addr.sin_port,你告訴bind()自己選擇合適的端口。同樣,將my_addr.sin_addr.s_addr設(shè)置為INADDR_ANY,你告訴它自動填上它所運行的機器的IP地址。簡單得很不是嗎?再看看例子:bind()函數(shù)bind()在錯誤的時候依然是返回-1,并且使用WSAGetLastError()取錯。在你調(diào)用bind()的時候,你要小心的另一件事情是:不要采用小于1024的端口號。所有小于1024的端口號都被系統(tǒng)保留!你可以選擇從1024到65535的端口(如果它們沒有被別的程序使用的話)。你要注意的另外一件小事是:有時候你根本不需要調(diào)用它。如果你使用connect()來和遠(yuǎn)程機器進行通訊,你不需要關(guān)心你的本地端口號(就象你在使用telnet的時候),你只要簡單的調(diào)用connect()就可以了,它會檢查套接字是否綁定端口,如果沒有,它會自己綁定一個沒有使用的本地端口。connect()函數(shù)connect()程序
現(xiàn)在我們假設(shè)你是個telnet程序。你的用戶命令你得到套接字的文件描述符。你聽從命令調(diào)用了socket()。下一步,你的用戶告訴你通過端口23(標(biāo)準(zhǔn)telnet端口)連接到"0"。你該怎么做呢?幸運的是,你正在閱讀connect()--如何連接到遠(yuǎn)程主機這一章。你可不想讓你的用戶失望。
connect()系統(tǒng)調(diào)用是這樣的:
intconnect(intsockfd,structsockaddr*serv_addr,intaddrlen);sockfd是系統(tǒng)調(diào)用socket()返回的套接字文件描述符。serv_addr是保存著目的地端口和IP地址的數(shù)據(jù)結(jié)構(gòu)structsockaddr。addrlen設(shè)置為sizeof(structsockaddr)。想知道得更多嗎?讓我們來看個例子:之后,你應(yīng)該檢查connect()的返回值--它在錯誤的時候返回-1,并通過WSAGetLastError()取錯。
同時,你可能看到,我沒有調(diào)用bind()。因為我不在乎本地的端口號。我只關(guān)心我要去那。內(nèi)核將為我選擇一個合適的端口號,而我們所連接的地方也自動地獲得這些信息。一切都不用擔(dān)心。listen()函數(shù)是換換內(nèi)容得時候了。假如你不希望與遠(yuǎn)程的一個地址相連,或者說,僅僅是將它踢開,那你就需要等待接入請求并且用各種方法處理它們。處理過程分兩步:首先,你聽--listen(),然后,你接受--accept()(請看下面的內(nèi)容)。
除了要一點解釋外,系統(tǒng)調(diào)用listen也相當(dāng)簡單。
intlisten(intsockfd,intbacklog);
sockfd是調(diào)用socket()返回的套接字文件描述符。backlog是在進入隊列中允許的連接數(shù)目。什么意思呢?進入的連接是在隊列中一直等待直到你接受(accept()請看下面的文章)連接。它們的數(shù)目限制于隊列的允許。大多數(shù)系統(tǒng)的允許數(shù)目是20,你也可以設(shè)置為5到10。和別的函數(shù)一樣,在發(fā)生錯誤的時候返回-1,并通過WSAGetLastError()取錯。
你可能想象到了,在你調(diào)用listen()前你或者要調(diào)用bind()或者讓內(nèi)核隨便選擇一個端口。如果你想偵聽進入的連接,那么系統(tǒng)調(diào)用的順序可能是這樣的:
socket();
bind();
listen();
accept()函數(shù)準(zhǔn)備好了,系統(tǒng)調(diào)用accept()會有點古怪的地方的!你可以想象發(fā)生這樣的事情:有人從很遠(yuǎn)的地方通過一個你在偵聽(listen())的端口連接(connect())到你的機器。它的連接將加入到等待接受(accept())的隊列中。你調(diào)用accept()告訴它你有空閑的連接。它將返回一個新的套接字文件描述符!這樣你就有兩個套接字了,原來的一個還在偵聽你的那個端口,新的在準(zhǔn)備發(fā)送(send())和接收(recv())數(shù)據(jù)。這就是這個過程!
intaccept(intsockfd,void*addr,int*addrlen);
sockfd相當(dāng)簡單,是和listen()中一樣的套接字描述符。addr是個指向局部的數(shù)據(jù)結(jié)構(gòu)sockaddr_in的指針。這是要求接入的信息所要去的地方(你可以測定那個地址在那個端口呼叫你)。在它的地址傳遞給accept之前,addrlen是個局部的整形變量,設(shè)置為sizeof(structsockaddr_in)。accept將不會將多余的字節(jié)給addr。如果你放入的少些,那么它會通過改
變addrlen的值反映出來。同樣,在錯誤時返回-1,并通過WSAGetLastError()取錯。
現(xiàn)在是你應(yīng)該熟悉的代碼片段。注意,在系統(tǒng)調(diào)用send()和recv()中你應(yīng)該使用新的套接字描述符new_fd。如果你只想讓一個連接進來,那么你可以使用close()去關(guān)閉原來的文件描述符sockfd來避免同一個端口更多的連接。send()andrecv()函數(shù)這兩個函數(shù)用于流式套接字或者數(shù)據(jù)報套接字的通訊。如果你喜歡使用無連接的數(shù)據(jù)報套接字,你應(yīng)該看一看下面關(guān)于sendto()和recvfrom()的章節(jié)。
send()是這樣的:
intsend(intsockfd,constvoid*msg,intlen,intflags);
sockfd是你想發(fā)送數(shù)據(jù)的套接字描述符(或者是調(diào)用socket()或者是accept()返回的。)msg是指向你想發(fā)送的數(shù)據(jù)的指針。len是數(shù)據(jù)的長度。把flags設(shè)置為0就可以了。(詳細(xì)的資料請看send()的manpage)。
這里是一些可能的例子:
char*msg="Beejwashere!";
intlen,bytes_sent;
.
.
len=strlen(msg);
bytes_sent=send(sockfd,msg,len,0);
send()andrecv()函數(shù)send()返回實際發(fā)送的數(shù)據(jù)的字節(jié)數(shù)--它可能小于你要求發(fā)送的數(shù)目!注意,有時候你告訴它要發(fā)送一堆數(shù)據(jù)可是它不能處理成功。它只是發(fā)送它可能發(fā)送的數(shù)據(jù),然后希望你能夠發(fā)送其它的數(shù)據(jù)。記住,如果send()返回的數(shù)據(jù)和len不匹配,你就應(yīng)該發(fā)送其它的數(shù)據(jù)。但是這里也有個好消息:如果你要發(fā)送的包很小(小于大約1K),它可能處理讓數(shù)據(jù)一次發(fā)送完。它在錯誤的時候返回-1,并通過WSAGetLastError()取錯。recv()函數(shù)很相似:
intrecv(intsockfd,void*buf,intlen,unsignedintflags);
sockfd是要讀的套接字描述符。buf是要讀的信息的緩沖。len是緩沖的最大長度。flags可以設(shè)置為0。(請參考recv()的manpage。)recv()返回實際讀入緩沖的數(shù)據(jù)的字節(jié)數(shù)。或者在錯誤的時候返回-1,并通過WSAGetLastError()取錯。
很簡單,不是嗎?你現(xiàn)在可以在流式套接字上發(fā)送數(shù)據(jù)和接收數(shù)據(jù)了。close()和shutdown()函數(shù)你已經(jīng)整天都在發(fā)送(send())和接收(recv())數(shù)據(jù)了,現(xiàn)在你準(zhǔn)備關(guān)閉你的套接字描述符了。這很簡單,你可以使用一般的Unix文件描述符的close()函數(shù):
close(sockfd);
它將防止套接字上更多的數(shù)據(jù)
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度辦公設(shè)備維修與升級服務(wù)合同5篇
- 二零二五年度汽車租賃合同租賃物維修保養(yǎng)費用承擔(dān)協(xié)議2篇
- 2025版風(fēng)力發(fā)電葉片設(shè)計與制造合同范本3篇
- 二零二五年度安全施工安全管理人員考核合同
- 二零二五年度數(shù)字貨幣研發(fā)團隊勞動合同2篇
- 二零二五年度農(nóng)產(chǎn)品批發(fā)市場店鋪承包管理協(xié)議3篇
- 二零二五年度代購合作協(xié)議范本匯編6篇
- 海南衛(wèi)生健康職業(yè)學(xué)院《學(xué)前兒童行為觀察與分析》2023-2024學(xué)年第一學(xué)期期末試卷
- 邯鄲科技職業(yè)學(xué)院《GIS氣象應(yīng)用與開發(fā)》2023-2024學(xué)年第一學(xué)期期末試卷
- 二零二五年度智慧社區(qū)建設(shè)政府采購項目委托代理協(xié)議書3篇
- 2025年湖南出版中南傳媒招聘筆試參考題庫含答案解析
- 2025年度商用廚房油煙機安裝與維護服務(wù)合同范本3篇
- 2024年03月恒豐銀行2024年春季招考畢業(yè)生筆試歷年參考題庫附帶答案詳解
- 網(wǎng)絡(luò)安全系統(tǒng)運維方案
- ISO 56001-2024《創(chuàng)新管理體系-要求》專業(yè)解讀與應(yīng)用實踐指導(dǎo)材料之14:“6策劃-6.3變更的策劃”(雷澤佳編制-2025B0)
- 2024年特厚板行業(yè)現(xiàn)狀分析:中國特厚板市場占總銷售量45.01%
- 2025年中國地質(zhì)調(diào)查局烏魯木齊自然資源綜合調(diào)查中心招聘19人歷年管理單位筆試遴選500模擬題附帶答案詳解
- 【公開課】同一直線上二力的合成+課件+2024-2025學(xué)年+人教版(2024)初中物理八年級下冊+
- 12G614-1砌體填充墻結(jié)構(gòu)構(gòu)造
- 路面輪胎模型建立方法swift
- 10KV供配電工程施工組織設(shè)計
評論
0/150
提交評論