第2章-套接字編程基礎(chǔ)_第1頁
第2章-套接字編程基礎(chǔ)_第2頁
第2章-套接字編程基礎(chǔ)_第3頁
第2章-套接字編程基礎(chǔ)_第4頁
第2章-套接字編程基礎(chǔ)_第5頁
已閱讀5頁,還剩67頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、第2章 Socket編程接口楊 明紫金學院計算機系網(wǎng)絡(luò)編程2022-6-22內(nèi)容nWinsock網(wǎng)絡(luò)編程接口 n面向連接的套接字編程 n無連接的套接字編程WinSock編程接口nWindows Socktes規(guī)范 nMicrosoft公司以Berkeley Sockets規(guī)范為范例,定義了Windows Socktes規(guī)范,簡稱Winsock規(guī)范。這是Windows操作系統(tǒng)環(huán)境下的套接字網(wǎng)絡(luò)應(yīng)用程序編程接口(API)。nWindows Sockets 規(guī)范是一套開放的、支持多種協(xié)議的Windows下的網(wǎng)絡(luò)編程接口。從1991年到1995年,從1.0版發(fā)展到2.2版,已成為Windows網(wǎng)絡(luò)編程

2、的事實上的標準。WinSock2 編程模型4 4WinSock2 編程模型5 5WINSOCK2工作模式6 6Winsock函數(shù)n初始化函數(shù)n基本的Winsock函數(shù)n數(shù)據(jù)傳輸函數(shù)n輔助函數(shù)n信息查詢函數(shù)n錯誤處理函數(shù)Winsock初始化函數(shù)Winsock初始化函數(shù)n初始化函數(shù)初始化函數(shù)WSAStartup()nWinsock 應(yīng)用程序要做的第一件事,就是必須首先調(diào)用WSAStartup()函數(shù)對Winsock進行初始化,成功后,才能調(diào)用其他的Winsock API函數(shù)。nWSAStartup()函數(shù)的調(diào)用格式函數(shù)的調(diào)用格式nint WSAStartup( WORD wVersionReque

3、sted, LPWSADATA lpWSAData );n用法nWSADATA WsaDatnWSAStartup(MAKEWORD(2,2), &WsaDat);Winsock初始化函數(shù)n注銷函數(shù)注銷函數(shù)WSACleanup()n當程序使用完Winsock.DLL提供的服務(wù)后,應(yīng)用程序必須調(diào)用WSACleanup()函數(shù),來解除與Winsock.DLL庫的綁定,釋放Winsock實現(xiàn)分配給應(yīng)用程序的系統(tǒng)資源,中止對Windows Sockets DLL的使用。 nint WSACleanup ( void ); 基本的Winsock函數(shù)n創(chuàng)建套接字-socket函數(shù)n綁定套接字-bi

4、nd函數(shù)n請求連接-connect函數(shù)n監(jiān)聽連接-listen函數(shù)n接受連接-accept函數(shù)n斷開套接字-shutdown函數(shù)n關(guān)閉套接字-closesocket函數(shù)創(chuàng)建套接字nsocket()nsocket過程創(chuàng)建一個套接字并返回一個整型描述符n格式:int SOCKET( int Protofamily, int Type, int Protocol); n參數(shù)1: 說明使用協(xié)議簇,對于IPv4,設(shè)置為AF_INETn參數(shù)2:說明套接字類型,如SOCK_STREAM,SOCK_DGRAMn參數(shù)3:采用的底層協(xié)議,設(shè)為0時為套接字服務(wù)自動選擇n套接字創(chuàng)建成功,則返回套接字描述符,否則返回I

5、NVALID_SOKET錯誤nSOCKET sockfd=SOCKET( AF_INET, SOCK_STREAM, 0); /* 創(chuàng)建一個流式套接字。nSOCKET sockfd=SOCKET( AF_INET, SOCK_DGRAM, 0); /* 創(chuàng)建一個數(shù)據(jù)報套接字。 套接字綁定nbind()n多用于服務(wù)器將創(chuàng)建的套接字與制定的網(wǎng)絡(luò)地址進行綁定,客戶端一般不需綁定nint BIND( int Sockfd, struct sockaddr* My_addr, int Addrlen); n參數(shù)1:套接字標識符n參數(shù)2:要綁定的網(wǎng)絡(luò)地址n參數(shù)3:網(wǎng)絡(luò)地址結(jié)構(gòu)的長度n返回值:若返回0表示正

6、確綁定,否則返回SOCKET_ERROR表示有錯。套接字使用的地址數(shù)據(jù)類型nsockaddr_in結(jié)構(gòu),專門針對Internet通信域,存儲套接字相關(guān)的網(wǎng)絡(luò)地址信息,例如IP地址,傳輸層端口號等信息。struct sockaddr_in short int sin_family; / 地址家族unsigned short int sin_port; / 端口號struct in_addr sin_addr; / IP 地址unsigned char sin_zero8; / 全為0 SOCKET serSock; / 定義了一個SOCKET 類型的變量。sockaddr_in my_addr;

7、 / 定義一個Sockaddr_in型的結(jié)構(gòu)實例變量。int err; / 出錯碼。 int slen=sizeof( sockaddr); / sockaddr 結(jié)構(gòu)的長度。serSock = socket(AF_INET, SOCK_DGRAM,0 ); / 創(chuàng)建數(shù)據(jù)報套接字。memset(my_addr,0); / 將Sockaddr_in的結(jié)構(gòu)實例變量清零。my_addr.sin_family = AF_INET; / 指定通信域是Internet。my_addr.sin_port = htons(21); / 指定端口,將端口號轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)順序。 創(chuàng)建套接字示例/* 指定IP地址,

8、將IP地址轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)順序。my_addr.sin_addr.s_addr = htonl( INADDR-ANY); /* 將套接字綁定到指定的網(wǎng)絡(luò)地址,對&my_addr進行了強制類型轉(zhuǎn)換。if (BIND(serSock, (LPSOCKADDR )&my_addr, slen) = SOCKET_ERROR ) /* 調(diào)用WSAGetLastError()函數(shù),獲取最近一個操作的錯誤代碼。 err = WSAGetLastError(); /* 以下可以報錯,進行錯誤處理。 套接字綁定示例請求連接nconnect()n僅用于客戶端,用來請求建立服務(wù)器連接n格式:int

9、 connect( int sockfd, struct sockaddr * name, int namelen); n返回值:連接成功,返回0;否則返回-1nif (connect(sockfd, (struct sockaddr*)(&serv_addr),sizeof(struct sockaddr)0) 報錯,并退出 請求連接n舉例nstruct sockaddr_in daddr;nmemset(void *)&daddr,0,sizeof(daddr);ndaddr.sin_family=AF_INET;ndaddr.sin_port=htons(8888);nd

10、addr.sin_addr.s_addr=inet_addr(133.197.22.4);nIf (connect(ClientSocket,(struct sockaddr *)&daddr,sizeof(daddr)0) 報錯,并退出 ;啟動監(jiān)聽nlisten()n告訴服務(wù)器端套接字開始監(jiān)聽客戶機的連接請求n格式:int listen(int Socket, int Queuesize)接受連接請求naccept()n格式:int accept( int sockfd, struct sockaddr* addr, int* addrlen);n返回值:如執(zhí)行正確,返回新的套接字描

11、述符,該套接字已和請求的客戶端建立連接;否則出錯返回-1.n舉例:nint clientfd; / 定義響應(yīng)套接字描述符變量nint addrler=sizeof(sockaddr); / 獲得套接字地址結(jié)構(gòu)長度。nstruct sockaddr_in cltsockaddr; / 定義返回客戶端地址的結(jié)構(gòu)nclientfd=ACCEPT(listenfd, (sockaddr* )(&cltsockaddr), &addrlen); / 接收客戶連接請求 斷開與關(guān)閉套接字n斷開套接字shutdown()n禁止在一個套接口上進行數(shù)據(jù)的接收與發(fā)送n格式:int shutdown(

12、 int sockfd, int how)nSD_SENDnSD_RECEIVEnSD_BOTHn關(guān)閉套接字closesocket()n關(guān)閉套接字,釋放資源n格式:int closesocket( int sockfd)數(shù)據(jù)傳輸函數(shù)nsend()n向一個已連接的套接字發(fā)送數(shù)據(jù)n格式: int send( int sockfd, char * buf, int len, int flags);n正確返回實際發(fā)送的字節(jié)數(shù),否則返回-1數(shù)據(jù)傳輸函數(shù)nrecv()n從已建立的套接字接收數(shù)據(jù)n格式: int recv( int sockfd, char * buf, int len, int flags

13、);n正確返回實際發(fā)送的字節(jié)數(shù),否則返回-1Winsock的輔助函數(shù)nWinsock中的字節(jié)順序轉(zhuǎn)換函數(shù)中的字節(jié)順序轉(zhuǎn)換函數(shù)n兩種本機字節(jié)順序本機字節(jié)順序和網(wǎng)絡(luò)字節(jié)順序n本機字節(jié)順序n在具體計算機中的多字節(jié)數(shù)據(jù)的存儲順序n網(wǎng)絡(luò)字節(jié)順序n多字節(jié)數(shù)據(jù)在網(wǎng)絡(luò)協(xié)議報頭中的存儲順序n不同字節(jié)順序的轉(zhuǎn)換n應(yīng)用程序在編程的時候,在把IP地址和端口號裝入套接字的時候,應(yīng)當把它們從本機字節(jié)順序轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)順序;n相反,在本機輸出時,應(yīng)將它們從網(wǎng)絡(luò)字節(jié)順序轉(zhuǎn)換為本機字節(jié)順序。 字節(jié)序轉(zhuǎn)換函數(shù)nhtons() 短整數(shù)本機順序轉(zhuǎn)換為網(wǎng)絡(luò)順序,用于端口號。nhtonl() 長整數(shù)本機順序轉(zhuǎn)換為網(wǎng)絡(luò)順序,用于IP地址。

14、nntohs() 短整數(shù)網(wǎng)絡(luò)順序轉(zhuǎn)換為本機順序,用于端口號。nntohl() 長整數(shù)網(wǎng)絡(luò)順序轉(zhuǎn)化為本機順序,用于IP地址。(1)htonl() 將主機的無符號長整型數(shù)本機順序轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)順序 (Host to Network Long),用于IP地址。u_long PASCAL FAR htonl( u_long hostlong); hostlong是主機字節(jié)順序表達的32位數(shù)。htonl()返回一個網(wǎng)絡(luò)字節(jié)順序的值。(2)htons() 將主機的無符號短整型數(shù)轉(zhuǎn)換成網(wǎng)絡(luò)字節(jié)順序(Host to Network Short),用于端口號。u_short PASCAL FAR htons(

15、u_short hostshort);hostshort:主機字節(jié)順序表達的16位數(shù)。htons()返回一個網(wǎng)絡(luò)字節(jié)順序的值。 字節(jié)序轉(zhuǎn)換函數(shù)(3)ntohl()將一個無符號長整型數(shù)從網(wǎng)絡(luò)字節(jié)順序轉(zhuǎn)換為主機字節(jié)順序。用于IP地址。u_long PASCAL FAR ntohl( u_long netlong); netlong是一個以網(wǎng)絡(luò)字節(jié)順序表達的32位數(shù),ntohl()返回一個以主機字節(jié)順序表達的數(shù)。(4)ntohs()將一個無符號短整型數(shù)從網(wǎng)絡(luò)字節(jié)順序轉(zhuǎn)換為主機字節(jié)順序。用于端口號u_short PASCAL FAR ntohs( u_short netshort);netshort是

16、一個以網(wǎng)絡(luò)字節(jié)順序表達的16位數(shù)。ntohs()返回一個以主機字節(jié)順序表達的數(shù)。 字節(jié)序轉(zhuǎn)換函數(shù)2獲取與套接口相連的端地址獲取與套接口相連的端地址GETPEERNAME()int getpeername( SOCKET s, struct sockaddr * name, int * namelen); 3獲取一個套接口的本地名字獲取一個套接口的本地名字GETSOCKNAME()int getsockname( SOCKET s, struct sockaddr * name, int * namelen); 4將一個點分十進制形式的將一個點分十進制形式的IP地址轉(zhuǎn)換成一個長整型數(shù)地址轉(zhuǎn)換成一

17、個長整型數(shù)INET_ADDR()unsigned long inet_addr (const char * cp); 5 將 網(wǎng) 絡(luò) 地 址 轉(zhuǎn) 換 成 點 分 十 進 制 的 字 符 串 格 式 將 網(wǎng) 絡(luò) 地 址 轉(zhuǎn) 換 成 點 分 十 進 制 的 字 符 串 格 式INET_NTOA()char * inet_ntoa( struct in_addr in); Winsock的信息查詢函數(shù)nGethostname()n用來返回本地計算機的標準主機名。nint gethostname(char* name, int namelen);nGethostbyname()n返回對應(yīng)于給定主機名的

18、主機信息。nstruct hostent* gethostbyname(const char* name);nGethostbyaddr()n根據(jù)一個IP地址取回相應(yīng)的主機信息。nstruct hostent* gethostbyaddr(const char* addr, int len, int type);nGetservbyname()n返回對應(yīng)于給定服務(wù)名和協(xié)議名的相關(guān)服務(wù)信息。nstruct servent* getservbyname(const char* name, const char* proto);主機名解析nGethostbynamen我們使用域名來標識站點,可以將文

19、字型的主機域名直接轉(zhuǎn)換成IP地址n格式:struct hostent* gethostbyname( const char* name);n入口參數(shù):是站點的主機域名字符串,n返回值: 是指向hostent 結(jié)構(gòu)的指針,失敗返回NULLnhostent結(jié)構(gòu)包含主機名,主機別名數(shù)組,返回地址的類型(一般是AF-INET),地址長度的字節(jié)數(shù),已符合網(wǎng)絡(luò)字節(jié)順序的主機網(wǎng)絡(luò)地址等。n將轉(zhuǎn)換后的IP地址復(fù)制到服務(wù)器的地址結(jié)構(gòu)中 Winsock的信息查詢函數(shù)n除了Gethostname()函數(shù)以外,其它六個函數(shù)有以下共同的特點:n函數(shù)名都采用GetXbyY的形式。 n如果函數(shù)成功地執(zhí)行,就返回一個指向某種

20、結(jié)構(gòu)的指針,該結(jié)構(gòu)包含所需要的信息。n如果函數(shù)執(zhí)行發(fā)生錯誤,就返回一個空指針。應(yīng)用程序可以立即調(diào)用WSAGetLastError()來得到一個特定的錯誤代碼。n函數(shù)執(zhí)行時,可能在本地計算機上查詢,也可能通過網(wǎng)絡(luò)向域名服務(wù)器發(fā)送請求,來獲得所需要的信息,這取決于用戶網(wǎng)絡(luò)的配置方式。WINSOCK程序結(jié)構(gòu)n新建一個Win32 API空項目ninclude必需的頭文件n鏈接Winsock庫文件WS2_32.libn開始Winsock應(yīng)用程序編程3333#include / include必需的頭文件#include #include #pragma comment(lib, Ws2_32.lib)

21、/鏈接Winsock庫文件WS2_32.libint main() /開始Winsock應(yīng)用程序編程 return 0;不同類型套接字編程n通信方式nC/S模式與P2P模式n不同連接方式n面向連接與面向無連接n阻塞方式n阻塞模式與非阻塞模式n可以進行組合形成不同類型的網(wǎng)絡(luò)編程面向連接的套接字工作過程 面向連接客戶機編程3636n面向連接客戶機編程步驟(阻塞模式)(1)初始化Winsock服務(wù)(2)創(chuàng)建套接字(3)主機名解析,配置套接字要訪問的服務(wù)器的地址結(jié)構(gòu)信息(4)連接服務(wù)器(5)從服務(wù)接收信息并顯示(6)斷開套接字連接,不允許發(fā)送數(shù)據(jù),但可以繼續(xù)接收數(shù)據(jù)(7)關(guān)閉套接字,釋放資源(8)關(guān)閉

22、Winsock服務(wù)完整的客戶機程序-(1)#include #include #pragma comment(lib,ws2_32.lib)int main()WSADATA WsaDat; / 初始化 Winsock服務(wù)if(WSAStartup(MAKEWORD(2,2),&WsaDat)!=0)std:coutWinsock錯誤 - Winsock服務(wù)初始化失敗!rn;WSACleanup();system(PAUSE);return 0;SOCKET Socket=socket(AF_INET,SOCK_STREAM,0); / 創(chuàng)建套接字if(Socket=INVALID_S

23、OCKET)std:cout套接字錯誤 -創(chuàng)建套接字失敗!rn;WSACleanup();system(PAUSE);return 0;struct hostent *host; / 主機名解析if(host=gethostbyname(localhost)=NULL)std:couth_addr);/ 連接服務(wù)器if(connect(Socket,(SOCKADDR*)(&SockAddr),sizeof(SockAddr)!=0)std:cout與服務(wù)器連接失敗!rn;WSACleanup();system(PAUSE);return 0; 完整的客戶機程序-(2) / 從服務(wù)接收

24、信息并顯示char buffer1024;memset(buffer,0,1023);int inDataLength=recv(Socket,buffer,1024,0);std:coutbuffer;/ 斷開套接字連接,不允許發(fā)送數(shù)據(jù),但可以繼續(xù)接收數(shù)據(jù)shutdown(Socket,SD_SEND);/ 關(guān)閉套接字,釋放資源closesocket(Socket);/ 關(guān)閉Winsock服務(wù),清理內(nèi)存WSACleanup();system(PAUSE);return 0;完整的客戶機程序-(3)面向連接服務(wù)器編程n阻塞模式服務(wù)器編程步驟阻塞模式服務(wù)器編程步驟(1)啟動并初始化Winsock

25、2服務(wù)(與客戶機同)(2)創(chuàng)建Socket(與客戶機同)(3)填充服務(wù)器地址、端口信息(有變化)(4)綁定服務(wù)器地址信息到套接字(新增步驟)(5)偵聽客戶連接(新增步驟)(6)接受客戶連接(新增步驟)(7)向客戶機發(fā)送數(shù)據(jù)(8)斷開套接字連接,停止發(fā)送數(shù)據(jù)(與客戶機同)(9)關(guān)閉套接字(與客戶機同)(10)關(guān)閉Winsock套接字服務(wù)(與客戶機同)4040完整的服務(wù)器程序-(1)#include #include #pragma comment(lib,ws2_32.lib)int main()WSADATA WsaDat;if(WSAStartup(MAKEWORD(2,2),&Ws

26、aDat)!=0)std:coutWinsock服務(wù)初始化失敗!rn;WSACleanup();system(PAUSE);return 0;SOCKET Socket=socket(AF_INET,SOCK_STREAM,0);if(Socket=INVALID_SOCKET)std:cout創(chuàng)建套接字失敗!rn;WSACleanup();system(PAUSE);return 0;SOCKADDR_IN serverInf;serverInf.sin_family=AF_INET;serverInf.sin_addr.s_addr=INADDR_ANY;serverInf.sin_por

27、t=htons(8888);if(bind(Socket,(SOCKADDR*)(&serverInf),sizeof(serverInf) =SOCKET_ERROR)std:cout不能綁定地址信息到套接字!rn;WSACleanup();system(PAUSE);return 0;listen(Socket,1);完整的服務(wù)器程序-(2)SOCKET TempSock=SOCKET_ERROR;while(TempSock=SOCKET_ERROR)std:cout服務(wù)器:正在等待來自客戶機的連接.rn;TempSock=accept(Socket,NULL,NULL); So

28、cket=TempSock;std:cout服務(wù)器:有客戶機連接到達!rnrn;char *szMessage=服務(wù)器說:有朋自遠方來來,不亦樂乎rn;send(Socket,szMessage,strlen(szMessage),0);shutdown(Socket,SD_SEND); / 斷開套接字連接,不允許發(fā)送數(shù)據(jù)closesocket(Socket); / 關(guān)閉套接字,釋放資源WSACleanup(); /關(guān)閉Winsock服務(wù),清理內(nèi)存system(PAUSE);return 0;完整的服務(wù)器程序-(3) RECV()函數(shù)的兩種執(zhí)行方式 Winsock的I/O模式 有多個操作套接字

29、的系統(tǒng)調(diào)用會引起進程阻塞。有多個操作套接字的系統(tǒng)調(diào)用會引起進程阻塞。(1)ACCEPT()(2)READ()、RECV()和和READFORM()(3)WRITE()、SEND()和和SENDTO()(4)CONNECT()(5)SELECT()(6)CLOSESOCKET() 能引起阻塞的套接字調(diào)用 采用阻塞工作模式的單進程服務(wù)器是不能很好采用阻塞工作模式的單進程服務(wù)器是不能很好地同時為多個客戶服務(wù)的。地同時為多個客戶服務(wù)的。阻塞工作模式帶來的問題非阻塞模式客戶機編程n設(shè)置套接字阻塞模式nioctlsocket(Socket,FIONBIO,&iMode); n如果設(shè)置iMode=0

30、 ,套接字將處于阻塞模式n設(shè)置iMode=1,套接字工作于非阻塞模式。n缺省狀態(tài)為阻塞模式n其他不同步驟n需要一個循環(huán)來處理數(shù)據(jù)接收過程非阻塞模式客戶機編程for(;) / 主循環(huán)/ 接收服務(wù)器信息char buffer1024;memset(buffer,0,1023);int inDataLength=recv(Socket,buffer,1024,0);std:coutbuffer;int nError=WSAGetLastError();if(nError!=WSAEWOULDBLOCK&nError!=0)/ 斷開套接字,只能接收不能發(fā)送shutdown(Socket,SD_

31、SEND);closesocket(Socket); / 關(guān)閉套接字break;Sleep(1000);非阻塞模式服務(wù)器編程1.初始化套接字2.創(chuàng)建套接字3.配置SOCKADDR_IN地址信息4.在套接字上偵聽5.接受來自客戶機的連接6.設(shè)置套接字工作模式nu_long iMode=1;nioctlsocket(Socket,FIONBIO,&iMode);for(;) / 主循環(huán) char *szMessage=非阻塞服務(wù)器說:有朋自遠方來來,不亦樂乎rn; send(Socket,szMessage,strlen(szMessage),0); int nError=WSAGetLa

32、stError(); if(nError!=WSAEWOULDBLOCK&nError!=0)std:coutWinsock錯誤碼為: nErrorrn;std:cout客戶機斷開連接!rn;/ 斷開套接字連接,不允許發(fā)送,可以接收shutdown(Socket,SD_SEND);/ 關(guān)閉套接字closesocket(Socket);break;Sleep(1000);非阻塞模式服務(wù)器編程非阻塞模式服務(wù)器完整代碼#include #include #pragma comment(lib,ws2_32.lib)int main()WSADATA WsaDat;if(WSAStartup(

33、MAKEWORD(2,2),&WsaDat)!=0)std:coutWinsock服務(wù)初始化失敗!rn;WSACleanup();system(PAUSE);return 0;SOCKET Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if(Socket=INVALID_SOCKET)std:cout創(chuàng)建套接字失??!rn;WSACleanup();system(PAUSE); return 0;非阻塞模式服務(wù)器完整代碼SOCKADDR_IN serverInf;serverInf.sin_family=AF_INET;serverInf.

34、sin_addr.s_addr=INADDR_ANY;serverInf.sin_port=htons(8888);if(bind(Socket,(SOCKADDR*)(&serverInf),sizeof(serverInf)=SOCKET_ERROR)std:cout套接字綁定失敗!rn;WSACleanup();system(PAUSE);return 0;listen(Socket,1);SOCKET TempSock=SOCKET_ERROR;while(TempSock=SOCKET_ERROR)std:cout服務(wù)器:正在等待客戶機連接.rn;TempSock=accep

35、t(Socket,NULL,NULL); 非阻塞模式服務(wù)器完整代碼u_long iMode=1; / iMode!=0表示阻塞模式ioctlsocket(Socket,FIONBIO,&iMode);Socket=TempSock;std:cout服務(wù)器說:有新客戶機連接到達!rnrn;for(;) / 主循環(huán)char *szMessage=非阻塞服務(wù)器說:有朋自遠方來來,不亦樂乎rn;send(Socket,szMessage,strlen(szMessage),0);int nError=WSAGetLastError();if(nError!=WSAEWOULDBLOCK&

36、;nError!=0)std:coutWinsock錯誤碼為: nErrorrn;std:cout客戶機斷開連接!rn;shutdown(Socket,SD_SEND); / 斷開套接字closesocket(Socket); / 關(guān)閉套接字break;Sleep(1000);5454WSAStartup()函數(shù)執(zhí)行失敗時將返回一個Winsock錯誤碼。WSADATA WsaDat;if(WSAStartup(MAKEWORD(2,2),&WsaDat)!=0)std:coutWinsock服務(wù)初始化失敗!rn;WSACleanup();system(PAUSE);return 0;W

37、SADATA WsaDat;int nResult=WSAStartup(MAKEWORD(2,2),&WsaDat);if(nResult!=0)std:cout Winsock服務(wù)初始化失敗,錯誤碼: nResultrn;WSACleanup();system(PAUSE);return 0;套接字錯誤處理套接字錯誤處理錯誤處理錯誤處理2 2:接下來的代碼是創(chuàng)建套接字,創(chuàng)建不成功怎么辦?把程序2.5中的代碼稍作如下修改即可捕獲錯誤原因:SOCKET Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);If (Socket=INVALID_S

38、OCKET)int nError=WSAGetLastError();std:cout創(chuàng)建套接字失敗,錯誤碼:nErrorrn;WSACleanup();system(PAUSE);return 0;套接字錯誤處理錯誤處理錯誤處理3 3:成功創(chuàng)建套接字后,接下來的步驟是配置SOCKADDR_IN地址結(jié)構(gòu)信息然后進行套接字綁定,綁定過程發(fā)生錯誤怎么辦?if(bind(Socket,(SOCKADDR*)(&serverInf),sizeof(serverInf)=SOCKET_ERROR)int nError=WSAGetLastError();std:cout不能綁定地址信息到套接字,

39、錯誤碼: nError 0 ) printf(Server: Total Bytes received: %dn, ByteReceived); else printf(Server: recvfrom() failed th error code: %dn, WSAGetLastError();客戶端程序#include #include int main(int argc, char *argv)WSADATA wsaData;SOCKET SendingSocket;SOCKADDR_IN ReceiverAddr, SrcInfo;char *SendBuf = Sending all

40、 my love to you!;int Port = 5150 , BufLength = 1024,len, TotalByteSent;/ 初始化Winsock version 2.2if( WSAStartup(MAKEWORD(2,2), &wsaData) != 0)printf(Client: WSAStartup error %ldn, WSAGetLastError();WSACleanup(); / Clean upreturn -1; / Exit with error/ 創(chuàng)建收發(fā)UDP消息的套接字SendingSocket = socket(AF_INET, S

41、OCK_DGRAM, IPPROTO_UDP);if (SendingSocket = INVALID_SOCKET)printf(Client: Error at socket(): %ldn, WSAGetLastError();WSACleanup(); / Clean upreturn -1; / Exit with errorReceiverAddr.sin_family = AF_INET;ReceiverAddr.sin_port = htons(Port);ReceiverAddr.sin_addr.s_addr = inet_addr(127.0.0.1);/ 發(fā)送數(shù)據(jù)報pr

42、intf(Client: Sending datagrams.n);TotalByteSent = sendto(SendingSocket, SendBuf, BufLength, 0, (SOCKADDR *)&ReceiverAddr, sizeof(ReceiverAddr);printf(Client: sendto() looks OK!n);memset(&SrcInfo, 0, sizeof(SrcInfo);len = sizeof(SrcInfo);getsockname(SendingSocket, (SOCKADDR *)&SrcInfo, &a

43、mp;len);printf(Client: Sending IP(s) used: %sn, inet_ntoa(SrcInfo.sin_addr);printf(Client: Sending port used: %dn, htons(SrcInfo.sin_port);/ Some info on the sender sidegetpeername(SendingSocket, (SOCKADDR *)&ReceiverAddr, (int *)sizeof(ReceiverAddr);printf(Client: Receiving IP used: %sn, inet_n

44、toa(ReceiverAddr.sin_addr);printf(Client: Receiving port used: %dn, htons(ReceiverAddr.sin_port);/ When your application is finished receiving datagrams close the socket.if (closesocket(SendingSocket) != 0) printf(Client: closesocket() failed! Error code: %ldn, WSAGetLastError(); / When your applica

45、tion is finished call WSACleanup.if(WSACleanup() != 0) printf(Client: WSACleanup() failed! Error code: %ldn, WSAGetLastError(); system(pause); return 0;服務(wù)器端程序#include #include int main(int argc, char *argv)WSADATAwsaData; SOCKET ReceivingSocket;SOCKADDR_INReceiverAddr, SenderAddr;intPort = 5150, Buf

46、Length = 1024;charReceiveBuf1024;intSenderAddrSize = sizeof(SenderAddr), ByteReceived = 5; if( WSAStartup(MAKEWORD(2,2), &wsaData) != 0) printf(Server: WSAStartup failed error %ldn, WSAGetLastError(); return -1; ReceivingSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (ReceivingSocket = INVALID_SOCKET)printf(Server: Error at 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)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論