TCPIP網絡編程與C代碼示例_第1頁
TCPIP網絡編程與C代碼示例_第2頁
TCPIP網絡編程與C代碼示例_第3頁
TCPIP網絡編程與C代碼示例_第4頁
TCPIP網絡編程與C代碼示例_第5頁
已閱讀5頁,還剩20頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、TCP/IP網絡編程與C代碼示例摘要:本文主要內容包括:TCP/IP網絡編程中用到的基本概念,在Win32下使用 wrnsock進行編程的指導以及對應的源碼。在OSI的各層所使用的協(xié)議:1. 應用層:Telnet,FTP,HTTP.DNS,SMTP.POP32. 傳輸層:TCP.UDPTCP:而向連接的可靠的傳輸協(xié)議,通信前建立三次握手,握手成功后才能通信, 對數(shù)據(jù)準確性要求較高的場合使用,如從網上載的安裝文件,不能缺少任何信息 UDP:是無連接的,不可靠的傳輸協(xié)議,不需要建立連接,也沒有重傳和確認的 機制,在實時性耍求較高,但對數(shù)據(jù)準確度要求不是很高的場合使用,如視頻會 議,在線觀看電影,當

2、中丟失個別數(shù)據(jù)包并不影響整體的效果。3. 網絡層:IP因為OSI七層結構較為復雜,所以使用較多的是TCP/1P模型,現(xiàn)在TCP/1 P 已經成為Internet上通用的工業(yè)標準TCP/1P模型包括4個層次:應用層,傳輸層,網絡層,網絡接口端口1. 為了標識通信實體中進行通信的進程(應用程序),TCP/1P協(xié)議提出了協(xié)議 端口的概念2. 端口是一種抽象的軟件結構(包括一些數(shù)據(jù)結構和I/O緩沖區(qū))。應用程序 通過系統(tǒng)調用和某端口建立連接(binding)后,傳輸層傳給該端口的數(shù)據(jù)都被 相應的進程所接收,相應進程發(fā)給傳輸層的數(shù)據(jù)都通過該端口輸出3. 端口用一個整數(shù)型標識符來表示,即端口號。端口號跟協(xié)

3、議相關,TCP/1P傳 輸層的兩個協(xié)議TCP和UDP是完全獨立的的兩個軟件模塊,因此各自的端口號 也相互獨立4. 端口使用一個16位的數(shù)字來表示,它的范圍是0-65535, 1024以下的端 口號保留給預定義的服務,例如,http使用80端口套接字(Socket)1.Socket的出現(xiàn),使得程序員可以很方便的訪問TCP/IP,從而開發(fā)各種網絡 應用的程序2. 套接字存在于通信區(qū)域中,通信區(qū)域也叫地址族,他是一個抽象的概念,主要 用丁通過套接通信的進程的共有特性綜合在一起。套接字通常只與同一個區(qū)域的套接字交換數(shù) 據(jù)。套接字的類型1. 流式套接字(SOCK_STREAM)提供面向連接的,可靠的數(shù)據(jù)

4、傳輸服務,數(shù)據(jù)無差錯,無重復的發(fā)送,且按發(fā)送 的順字接收,基于TCP協(xié)議2. 數(shù)據(jù)保式套接字(SOCK_DGRAM)提供無連接的服務,數(shù)據(jù)包以獨立包形式發(fā)送,不提供無錯誤的保證,數(shù)據(jù)可能丟失或重復,且接收順仔混亂,基于UDP協(xié)議基于TCP (面向連接)的Socket編程服務器端順序:1. 加載套接字庫2. 創(chuàng)建套接字(socket)3. 將套接字綁定到一個本地地址和端口上(bind)4. 將套接字設為監(jiān)聽模式,準備接收客戶請求(listen)5. 等待客戶請求的到來;當請求帶來后,接受連接請求,返回一個新的對應于此 次連接的套接字(accept)6. 用返回的套接字和客戶端進行通信(send/

5、recv)7. 返回,等待另一個客戶請求&關閉套接字(closesocket) 客戶端程序:1. 加載套接字庫2. 創(chuàng)建套接字(socket)3. 向服務器發(fā)送連接請求(connect)4 .和服務器端進行通信(send/receive)5 .關閉套接字(closesocket)基于UDP (面向無連接)的socket編程服務器端(接收端)程序:1. 加載套接字庫2創(chuàng)建套接字(socket)3. 將套接字綁定到一個本地地址和端口上(bind)4. 等待接收數(shù)據(jù)(iecvfrom)5 .關閉套接字(closesocket)客戶端(發(fā)送端)程序1. 加載套接字庫2創(chuàng)建套接字(socket)

6、3. 向服務器發(fā)送數(shù)據(jù)(sendto)4. 關閉套接寧(closesocket) 創(chuàng)建基于TCP協(xié)議的CS程序的Server端所涉及的相關函數(shù)說明(按使用的 先后順序排列):VVSAStartup (WORDwVersionRequested,LPVVSADATAlpVVSAData):作用是加載套接字庫和進行套接字庫的版本協(xié)商a.參數(shù)wVersioiiRequested:用于指定準備加載的Winsock庫的版本,高位字節(jié)指 定所需要的Wmsock庫的副版本,低位字節(jié)則是主版本,可用 MAKEWORD(X,Y)(其中,x為高位字節(jié),y為低位字節(jié))方便獲得 wVeisioiiReque

7、sted 的正確值。b.參數(shù)lpWSAData:指向WSADATA結構的指針,WSAStamip用其加載的庫版 本有關的信息填在這個結構中2.SOCKETsocket(intaf,inttvpe,intprotocoI):a. 參數(shù)af指定地址族,對于TCP/1P協(xié)議的套接字,它只能是AF_INET(也可 寫成 PF_INET)eb. 參數(shù)type指定Socket類型,對于1.1版本的Socket,它只支持兩種類型 的套接字,SOCK.STREAM指定產生流式套接字,SOCK.DGRAM產生數(shù)據(jù) 報套接字。c. 參數(shù)protocol與特定的地址家族相關的協(xié)議,如果指定為0,那么他就會根 據(jù)地址

8、格式和套接字類別,自動為你選擇一個合適的協(xié)議。這是推薦使用的一種 選擇協(xié)議的方式。3 .iiitbind(SOCKETs,coiiststructsockaddrFAR*iianieJntnanielen):a. 第一個參數(shù)指定要綁定的套接字,第一.個參數(shù)指定該套接字的本地地址信息, 是指向sockaddr結構的指針變暈,由于該地址結構是為了所有的地址家族準備 使用的,這個結構可能(通常會)隨使用的網絡協(xié)議不同而不同,所以,要用第 三個參數(shù)指定該地址結構的長度。sockaddr機構定義如下:struct sockaddru_shonsa_fanuly;cliaisa_data14;b. 上述結

9、構第一個字段指定該地址家族,在這里必須設為AF_INET。sa_data 僅僅是表示要求一塊內存分配區(qū),起到占位的作用,該區(qū)域中指定與協(xié)議相關的 具體地址信息。由于實際要求的只是內存區(qū),所以對于不同的協(xié)議家族,用不同 的結構來替換sockaddro在TCP/1 P中,我們可以用SOCKADDRJN結構來 代替sockaddr,以方便我們填寫地址信息。c. stmctSOCKADDR_IN slioitsm_fanuly;unsignedshonsin_poil;stiuctm_addisin_addi;chaisin_zero8;sin_family表示地址族,對于IP地址,sin_famil

10、y成員將一直是AF_INET: 成員sin.port指定的將要分配給套接字的端口;成員sin_addr給出的是套接 字的主機IP地址:sin_zero只是一個填充數(shù),以使sockaddr結構和 sockaddr結構的長度一樣,一般不用設置。除了 sm_fannly夕卜,SOCKADDR_IN M他成員是按網絡字節(jié)順序表示的。所以需 要進行轉換:hnml(INADDR_ANY), hK)ns(6000),其中 6000 是端口號。另外結構體的名稱大寫和小寫指的是同一個。將IP地址指定為INADDFLANY,允許套接字向任何分配給本機器的I P地址發(fā) 送或接收數(shù)據(jù)。一般一臺機器一個網卡,但對于多網

11、卡的機器,INADDR_ANY 將簡化應用程序的編寫。將地址指定為INADDR_ANY,允許一個獨立的應用接 受發(fā)自多個接口的回應。如果我們只想讓套接字使用多個IP中的一個地址,必 須指定實際地址,要做到這一點,可以用inet_addr()函數(shù),這個函數(shù)需要一個 IP地址(如8),返回一個適合分配給S_addr的u_long類型 的數(shù)值。lnet_ntoa()函數(shù)完成相反的轉換,它接受一個in_addr結構體類型 的參數(shù)并返回一個以點分十進制的IP地址字符串。htonl把一個u_long類型從主機字節(jié)序轉換為網絡字節(jié)序。htons把一個u_short類型從主機字節(jié)序轉換

12、為網絡字節(jié)序。4.intlisten(SOCKETs,intbacklog):將套接字設置為監(jiān)聽模式,其中第二個參 數(shù)設置等待請求連接的最大的值,即如果設置為n,貝IJ前n個請求會放置在系統(tǒng) 的請求連接隊列中,應用程序會依次對這些請求進行服務,但第n+1個連接諸 求則會被拒絕。5. SOCKET accept (SOCKETS, co nststructsockaddrFAR* addr,intFAR* ad drlen):從客戶端接收請求,并創(chuàng)建連接,如果連接成功,則會返回一個當前成功建立連 接的套接字,該套接字不是上面創(chuàng)建的監(jiān)聽套接字,而是僅僅適用于當前的一個 請求連接,如果建立連接失敗,

13、則返回值是INVALID_SOCKET,并且可以適用WSAGetLastError()函數(shù)得到相關的失敗信息,具體的errorcode具體意 義見MSDN中accept函數(shù)的最后部分的介紹6. send函數(shù):向客戶端發(fā)送指定信息7. recv函數(shù):得到從客戶端傳遞過來的信息8. closesocket(SOCKETs):將指定的套接字關閉,從而釋放資源9. WSACleaiiupO:終止對 vvuisocket 庫的使用10. hello服務器端的實現(xiàn)過程(Win32控制臺程序):說明:1. 對丁- winsock庫的類的使用,必須包倉wuisock2.li頭文件2. 在 setting 中的

14、 link 下的 object/libiaiymodules 中添加"ws2_32.1ib”,注意和前 面的字段之間用空格分隔3. 本服務器程序先于服務器端啟動#inchide"winsock2 .h”#include*'stdio.hMvoidmainQ加載套接了 (winsock)庫,加載這段代碼拷貝于MSDN中WSASianup的介紹W ORDwV ersioiiRequested;W SADAT AwsaData;interr;wVeisioiiRequested=MAKEWORD( 1,1);/版木號為 1.1en=WSAStainip(wVeisionR

15、equested,&wsaD3S);if(err?=O) return;if(LOBYTE(wsaData .wVersion)!=l|HIBYTE(wsaData.wVeision) !=1) WSACleanupQ;letuin;創(chuàng)建套接字SOCKETsockServeisocket(AF_INET,SOCK_STREAM,0);/SOCK_STREAM 參數(shù) 設置為TCP連接SOCKADDR.INaddiServer;/設置服務器琲;©接字的相關屬性 addiSeiver.sin_addr.S_un.S_addr=htonl(INADDR_ANY);設汽 IP addi

16、Seivei.sm_fanuly=AF_INET;addrServer.sin_port=htons(1234)y/設置端口號將套接字綁定到本地地址和指定端口上bind(sockSeiver,(SOCKADDR*)&addrServei,sizeof(SOCKADDR);將套接字設置為監(jiān)聽模式,并將最大請求連接數(shù)設置成5,超過此數(shù)的請求全 部作廢listen(sockSeivei,5);SOCKADDR.INaddrClient;/用來接收客戶端的設置,包括IP和端口mtlen=sizeof(SOCKADDR);while(l)/不斷監(jiān)聽得到創(chuàng)建連接后的一個新的套接字,用來和客戶端進行

17、溝通,原套接字繼續(xù)監(jiān) 聽客戶的連接諸求SOCKETsockConn=accept(sockSeivei,(SOCKADDR*)&addiClient,&len);if(sockCoim!=INVALID_SOCKET) 創(chuàng)建成功chai sendlnfo 100;/inet_ntoa將結構轉換為十進制的IP地址字符串spiintf(sendIiifd/,welcome%stotlustest?,uiet_ntoa(addClient.sin_addi);成功建立連接后向客戶端發(fā)送數(shù)據(jù),結果將顯示在客戶端上 send(sockCoiuLsendIiifd,stilen(sendI

18、nfb)+l,0);從客戶端接收數(shù)據(jù),結果顯水在服務器上cliairecvInfb100;recv(sockComi jecvlnfo, 100.0);prmtf(u%snH4ecvLifo);將本次建立連接屮得到套接字關閉closesocket(sockCoiin);elsemterrCode=WSAGetLastEnor();pruitf(ntheericodeis:%dn,eiiCode);如果本程序不是死循環(huán),那么在此處還應添加以下代碼: closesocket(sockServer)y/對一直處于監(jiān)聽狀態(tài)的套接字進行關閉 WSACleanup();/終止對 winsocket 庫的使

19、用創(chuàng)建基于TCP協(xié)議的CS程序的Client端所涉及的相關函數(shù)說明(按使用的先 后順序排列):l.mtWSAStaitiip ( WORDvVersioiiRequested,LPWSADATAlpWSAData ):說明 同上2.SOCKETsocket(intaf,mttvpe,intprotocol)說明同上3. connect函數(shù):同服務器建立連接4. send/recv發(fā)送與接收,同上5. closesocket:關閉套接字,同上客戶端的實現(xiàn)過程(win32console程序):說明:1. 對于wmsock庫的類的使用,必須包含wmsock2.h頭文件2. 在 setting 中的

20、link 卜的 object/libiaiymodules 中添加"ws2_32.1ib",注意和前 而的字段之間用空格分隔3. 啟動客戶端程序之前必須先啟動服務器端的程序#include,'wnisock2.11"# includeMstdio.hMvoidmain()加載套接字庫WORDwVeisioiiRequested;W SADAT AwsaData;mteir;wVersioiiRequested=MAKEWORD( 1,1);版本好為 1.1 eiF=WSAStamip(wVersionRequested, &wsaData); if

21、(eir?=O)retiun;if(LOBYTE(wsaData.wVersion)!=l|HIBYTE(wsaData.wVeision) !=1)WSACleanup();return,SOCKETsockClient=socket(AF_INET.SOCK_STREAM.O);/SOCK_STREAM 參數(shù) 設置為TCP連接SOCKADDR_INaddiSeiver; 服務器地址結構 addrServer.siicaddr.S_un.S_addr=met_addi(" ”);服務器地址 addiSeivei.sin_poit=htons( 1234)y/)|

22、z 務器端丨丨號addiSeiver. sin_fanuly=AF_INET;與服務器端建立連接,進行通信 intcoimReult=coimect(sockClient,(SOCKADDR*)&addiSenTer,sizeof(SOCKADDR) );if(comiReult?=WSAEADDRNOTAVAIL)/ 訪問戍功成功建立連接后向服務器端發(fā)送數(shù)據(jù),結果將顯示在服務器端上send(sockClient,"tlusislisi!,',stilen(,'thisiszhangsaii!,')+l,0);接收來r I服務器端發(fā)送來的信息chaii

23、ecvliifo100;recv(sockClient,recvIiifo, 100,0);pnntf(M%snnjecvLifo);else mtenCode=WSAGetLastEnor();pimttlieencodeisdVn'eiiCode);closesocket(sockClient);WSACleanupQ;創(chuàng)建基于UPD的CS程序服務器端源代碼:說明:服務器端的代碼在XP下運行recvfrom函數(shù)執(zhí)行不成功,返回一個10022的錯誤代碼, 參看網上資源,得知10022代表某個參數(shù)設置錯誤?;舜蟀胩斓臅r間研究后終于發(fā)現(xiàn)原來是6000端口在作怪,可能本機的UDP的600

24、0端口 在防火墻中被屏蔽了,通不過,但在TCP的CS程序中6000端口是通過的,程序調試一切 正常,將端口修改為其他端口即可# includeMwinsock2.h"# include"stdio.h"voidmain()加戟套接字(winsock)庫,加載這段代碼拷貝于MSDN中WSAStartup的介紹WORDwVersion Requested;WS A D AT A w sa D at a;interr;wVersionRoquestod= MAKEWORDf 1,1);/ 扳本號為 1 "1 err= WSAStartup( wVersion

25、Requested,&wsaData);if(err!=O) return;if(LOBYTE(wsaData.wVersion) = 111Hl BYTE(wsaData.wVersion) = 1) WSACIeanup();return;創(chuàng)建套接字注意第二個參數(shù)利TCP設置不同SOCKETsockServer= socket(AF_l NET,SOCK_DGRAM,0);SOCKADDRJNaddrServer;設置服務器端套接字的地址結構的相關屬性addrServer.sin_addr.S_un.S_addr= htonl(INADDR_ANY);/設汽 IP addrServ

26、er.sin_family= AF_INET;addrServer.sin_port= htons(6000);設這端口 巧將套接字和服務器地址結構綁定bind(sockServer,(SOCKADDR*)&addrServer,sizeof(SOCKADDR);SOCKADDR_INaddrClie nt;intlen= sizeof(SOCKADDR);charbuffer1OO;從客戶端接收數(shù)據(jù)intresult= recvf rom( sockServer, buff er, 100,0,( SOCKADDR* )&addrClient?&len); if(re

27、sult= = SOCKET_ERROR)interrCode= WSAGetLastError();printf(,error:%dwlerrCode);elseprin tf(Hthismessagefromclie nt:%s rT,buffer);closesocket (sockServer);WSACIeanup();創(chuàng)建基于UDP的CS程序客戶端的代碼:# includeMwinsock2.h"# includeMstdio.h"voidmain()加載套接字(winsock)庫,加載這段代碼拷貝于MSDN中WSAStartup的介紹WORDwVersion

28、Requested;WSADATAwsaData;interr;wVersionRequested= MAKEWORDf 1,1);/® 本號為 1.1err= WSAStartup( wVersion Requested,&wsaData);if(err!= 0)return; if (LOBYTE(wsaData.w Version) != 11HI BVTEfwsaData.w Version) = 1)WSACIeanup();return;創(chuàng)建套接字SOCKETsockClient二socket(AF_INESOCK_DGRAM,0);/注意第個參數(shù)和 TCP 設置

29、不同SOCKADDR_INaddrServer;/ 務器地址纟吉構addrServer.sin_addr.S_un.S_addr=inet_addr("127.0.0.r); 服務器地址addrServer.sin_fam ily= AF_INET;addrServer.sin_port= htons(6000);/服務器端l 丨號sen dto(sockClie ntthismessagefromclie nt”,strle n( ”thismessagefromclient”)+ 1,0,( SOCKADDR*)&addrServer,sizeof(SOCKADDR);c

30、losesocket (sockClie nt);WSACIeanup();基于UDP的聊天程序服務器端源程序:說明:1. 代碼基本和上述UDP服務器端的程序相類似,只是多了 sendto功能,即交互的功能2. 支持退出請求響應# include” winsock2.h"# include”stdio.h” voidmain()加載套接字(winsock)庫,加載這段代碼拷貝于MSDN中WSAStartup的介紹WORDw Version Requested;WSADATAwsaData;interr;w Version Request ed= MAKEWORD(1,1);/

31、1; 本號為 1.1err=WSAStartup(wVersion Requested,&wsaData);if(err!=O)return;if(LOBYTE(wsaData.wVersion) != 111HI B'fTE(wsaData.w Version) != 1)WSACIeanup();return;創(chuàng)建套接字注意第二個參數(shù)和TCP設置不同SOCKETsockServer=socket(AF_INET,SOCK_DGRAM,0);SOCKADDRJNaddrServer; 設置服務器端套接7的地址結構的相關屬竹addrServer.sin_addr.S_un.S_

32、addr= htonl(INADDR_ANY);/設進 IP addrServer.sin_family= AF_INET;addrServer.sin_port= htons(6000); 設逬端口號將套接字和服務器地址結構綁定bind(sockServer,(SOCKADDR*)&addrServer,sizeof(SOCKADDR);SOCKADDR_INaddrClie nt; intle n= sizeof (SOCKADDR); charrecvBuf100; chartempBuf 100; charsendBuf100;while(1)從客戶端接收數(shù)據(jù)intresult

33、= recvfrom(sockServer,recvBuf,100,0,(SOCKADDR* )&addrClient,&len);if(result= = SOCKET_ERROR)interrCode= WSAGet LastError();printferror:%cT,errCode);break; 退出循環(huán)elseif(recv Buf 0 = = 'q') 對方請求退出同樣將退出請求發(fā)送回去sendtofsockServer/q-.strlenC'q")+ 1,0,(SOCKADDR* )&addrClient,sizeof

34、(SOCKADDR);printf("thechatend!");break;else將對方發(fā)送過來的信息前段加上IP地址進行輸出 sprintf(tempBuf,w%ssaid:%s",inet_ntoa(addrClient.sin_addr),recvBuf);printf(H%sn,tempBuf);將用戶的德盤輸入發(fā)送到對方prin tf(Hpleasinputthemessage: rT);gets(sendBuf);/ 得 到 鍵 盤 輸 入 內 容 sen dto( sockServer, sendBuf, st rlen( send But) +

35、 1,0,(SOCKADDR* )&addrClient,sizeof (SOCKADDR);closesocket (sockServer);WSACIeanup();基于UDP的聊天程序客戶端端源程序:# includeMwinsock2.hH# includeRstdio.h"voidmain()加載套接字(winsock)庫,加載這段代碼拷貝于MSDN中WSAStartup的介紹WORDwVersion Requested;WSADATAwsaData;interr;wVersionRequested= MAKEWORD( 1,1); 版本號為 1.1 err= WS

36、AStartup( wVersion Requested,&wsaData);if(errlro)- recrn 八if(LOBYTE(wsaDatawverson)lr1 _ _ H- BTE(wsaDaiawversion)rl 二WSAC-eanup()八reiurn八SOCKETSOCkc=en 了 socka(AF一 NESOCKDGRAMo)/、H£-><這蘭 TCP 床北SOCKADDR一 NaddrServer V 二更羞吾=養(yǎng) addserversmladdrslunsladdr" ineiladdr (二 2700*T)awlhEad

37、dserversinlfami_y" AF-NET 八 addrserversinporF hions(6000)乏審莘呈 二 cha 二 empBufuoo】 八 charrecvBufuoo】八 charsendBufuoorr ini一 enusNeof(SOCKADDR) whi-e(l) priHf(p-eseinpu 二 hemessage 二 nh g2.2sendBuf);w 能堂迴 F3編睜勢 > sendio(sockc=ensendBuhs=-en(sendBuf) + 1o(SOCKADDFr )eoaddrserverszeof(SOCKADDR); intresult= recv

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論