版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、第2章 Socket編程接口楊 明紫金學(xué)院計(jì)算機(jī)系網(wǎng)絡(luò)編程2022-4-29內(nèi)容nWinsock網(wǎng)絡(luò)編程接口 n面向連接的套接字編程 n無(wú)連接的套接字編程WinSock編程接口nWindows Socktes規(guī)范 nMicrosoft公司以Berkeley Sockets規(guī)范為范例,定義了Windows Socktes規(guī)范,簡(jiǎn)稱Winsock規(guī)范。這是Windows操作系統(tǒng)環(huán)境下的套接字網(wǎng)絡(luò)應(yīng)用程序編程接口(API)。nWindows Sockets 規(guī)范是一套開(kāi)放的、支持多種協(xié)議的Windows下的網(wǎng)絡(luò)編程接口。從1991年到1995年,從1.0版發(fā)展到2.2版,已成為Windows網(wǎng)絡(luò)編程
2、的事實(shí)上的標(biāo)準(zhǔn)。WinSock2 編程模型4 4WinSock2 編程模型5 5WINSOCK2工作模式6 6Winsock函數(shù)n初始化函數(shù)n基本的Winsock函數(shù)n數(shù)據(jù)傳輸函數(shù)n輔助函數(shù)n信息查詢函數(shù)n錯(cuò)誤處理函數(shù)Winsock初始化函數(shù)Winsock初始化函數(shù)n初始化函數(shù)初始化函數(shù)WSAStartup()nWinsock 應(yīng)用程序要做的第一件事,就是必須首先調(diào)用WSAStartup()函數(shù)對(duì)Winsock進(jìn)行初始化,成功后,才能調(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當(dāng)程序使用完Winsock.DLL提供的服務(wù)后,應(yīng)用程序必須調(diào)用WSACleanup()函數(shù),來(lái)解除與Winsock.DLL庫(kù)的綁定,釋放Winsock實(shí)現(xiàn)分配給應(yīng)用程序的系統(tǒng)資源,中止對(duì)Windows Sockets DLL的使用。 nint WSACleanup ( void ); 基本的Winsock函數(shù)n創(chuàng)建套接字-socket函數(shù)n綁定套接字-bi
4、nd函數(shù)n請(qǐng)求連接-connect函數(shù)n監(jiān)聽(tīng)連接-listen函數(shù)n接受連接-accept函數(shù)n斷開(kāi)套接字-shutdown函數(shù)n關(guān)閉套接字-closesocket函數(shù)創(chuàng)建套接字nsocket()nsocket過(guò)程創(chuàng)建一個(gè)套接字并返回一個(gè)整型描述符n格式:int SOCKET( int Protofamily, int Type, int Protocol); n參數(shù)1: 說(shuō)明使用協(xié)議簇,對(duì)于IPv4,設(shè)置為AF_INETn參數(shù)2:說(shuō)明套接字類型,如SOCK_STREAM,SOCK_DGRAMn參數(shù)3:采用的底層協(xié)議,設(shè)為0時(shí)為套接字服務(wù)自動(dòng)選擇n套接字創(chuàng)建成功,則返回套接字描述符,否則返回I
5、NVALID_SOKET錯(cuò)誤nSOCKET sockfd=SOCKET( AF_INET, SOCK_STREAM, 0); /* 創(chuàng)建一個(gè)流式套接字。nSOCKET sockfd=SOCKET( AF_INET, SOCK_DGRAM, 0); /* 創(chuàng)建一個(gè)數(shù)據(jù)報(bào)套接字。 套接字綁定nbind()n多用于服務(wù)器將創(chuàng)建的套接字與制定的網(wǎng)絡(luò)地址進(jìn)行綁定,客戶端一般不需綁定nint BIND( int Sockfd, struct sockaddr* My_addr, int Addrlen); n參數(shù)1:套接字標(biāo)識(shí)符n參數(shù)2:要綁定的網(wǎng)絡(luò)地址n參數(shù)3:網(wǎng)絡(luò)地址結(jié)構(gòu)的長(zhǎng)度n返回值:若返回0表示正
6、確綁定,否則返回SOCKET_ERROR表示有錯(cuò)。套接字使用的地址數(shù)據(jù)類型nsockaddr_in結(jié)構(gòu),專門針對(duì)Internet通信域,存儲(chǔ)套接字相關(guān)的網(wǎng)絡(luò)地址信息,例如IP地址,傳輸層端口號(hào)等信息。struct sockaddr_in short int sin_family; / 地址家族unsigned short int sin_port; / 端口號(hào)struct in_addr sin_addr; / IP 地址unsigned char sin_zero8; / 全為0 SOCKET serSock; / 定義了一個(gè)SOCKET 類型的變量。sockaddr_in my_addr;
7、 / 定義一個(gè)Sockaddr_in型的結(jié)構(gòu)實(shí)例變量。int err; / 出錯(cuò)碼。 int slen=sizeof( sockaddr); / sockaddr 結(jié)構(gòu)的長(zhǎng)度。serSock = socket(AF_INET, SOCK_DGRAM,0 ); / 創(chuàng)建數(shù)據(jù)報(bào)套接字。memset(my_addr,0); / 將Sockaddr_in的結(jié)構(gòu)實(shí)例變量清零。my_addr.sin_family = AF_INET; / 指定通信域是Internet。my_addr.sin_port = htons(21); / 指定端口,將端口號(hào)轉(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ò)地址,對(duì)&my_addr進(jìn)行了強(qiáng)制類型轉(zhuǎn)換。if (BIND(serSock, (LPSOCKADDR )&my_addr, slen) = SOCKET_ERROR ) /* 調(diào)用WSAGetLastError()函數(shù),獲取最近一個(gè)操作的錯(cuò)誤代碼。 err = WSAGetLastError(); /* 以下可以報(bào)錯(cuò),進(jìn)行錯(cuò)誤處理。 套接字綁定示例請(qǐng)求連接nconnect()n僅用于客戶端,用來(lái)請(qǐng)求建立服務(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) 報(bào)錯(cuò),并退出 請(qǐng)求連接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) 報(bào)錯(cuò),并退出 ;啟動(dòng)監(jiān)聽(tīng)nlisten()n告訴服務(wù)器端套接字開(kāi)始監(jiān)聽(tīng)客戶機(jī)的連接請(qǐng)求n格式:int listen(int Socket, int Queuesize)接受連接請(qǐng)求naccept()n格式:int accept( int sockfd, struct sockaddr* addr, int* addrlen);n返回值:如執(zhí)行正確,返回新的套接字描
11、述符,該套接字已和請(qǐng)求的客戶端建立連接;否則出錯(cuò)返回-1.n舉例:nint clientfd; / 定義響應(yīng)套接字描述符變量nint addrler=sizeof(sockaddr); / 獲得套接字地址結(jié)構(gòu)長(zhǎng)度。nstruct sockaddr_in cltsockaddr; / 定義返回客戶端地址的結(jié)構(gòu)nclientfd=ACCEPT(listenfd, (sockaddr* )(&cltsockaddr), &addrlen); / 接收客戶連接請(qǐng)求 斷開(kāi)與關(guān)閉套接字n斷開(kāi)套接字shutdown()n禁止在一個(gè)套接口上進(jì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向一個(gè)已連接的套接字發(fā)送數(shù)據(jù)n格式: int send( int sockfd, char * buf, int len, int flags);n正確返回實(shí)際發(fā)送的字節(jié)數(shù),否則返回-1數(shù)據(jù)傳輸函數(shù)nrecv()n從已建立的套接字接收數(shù)據(jù)n格式: int recv( int sockfd, char * buf, int len, int flags
13、);n正確返回實(shí)際發(fā)送的字節(jié)數(shù),否則返回-1Winsock的輔助函數(shù)nWinsock中的字節(jié)順序轉(zhuǎn)換函數(shù)中的字節(jié)順序轉(zhuǎn)換函數(shù)n兩種本機(jī)字節(jié)順序本機(jī)字節(jié)順序和網(wǎng)絡(luò)字節(jié)順序n本機(jī)字節(jié)順序n在具體計(jì)算機(jī)中的多字節(jié)數(shù)據(jù)的存儲(chǔ)順序n網(wǎng)絡(luò)字節(jié)順序n多字節(jié)數(shù)據(jù)在網(wǎng)絡(luò)協(xié)議報(bào)頭中的存儲(chǔ)順序n不同字節(jié)順序的轉(zhuǎn)換n應(yīng)用程序在編程的時(shí)候,在把IP地址和端口號(hào)裝入套接字的時(shí)候,應(yīng)當(dāng)把它們從本機(jī)字節(jié)順序轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)順序;n相反,在本機(jī)輸出時(shí),應(yīng)將它們從網(wǎng)絡(luò)字節(jié)順序轉(zhuǎn)換為本機(jī)字節(jié)順序。 字節(jié)序轉(zhuǎn)換函數(shù)nhtons() 短整數(shù)本機(jī)順序轉(zhuǎn)換為網(wǎng)絡(luò)順序,用于端口號(hào)。nhtonl() 長(zhǎng)整數(shù)本機(jī)順序轉(zhuǎn)換為網(wǎng)絡(luò)順序,用于IP地址。
14、nntohs() 短整數(shù)網(wǎng)絡(luò)順序轉(zhuǎn)換為本機(jī)順序,用于端口號(hào)。nntohl() 長(zhǎng)整數(shù)網(wǎng)絡(luò)順序轉(zhuǎn)化為本機(jī)順序,用于IP地址。(1)htonl() 將主機(jī)的無(wú)符號(hào)長(zhǎng)整型數(shù)本機(jī)順序轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)順序 (Host to Network Long),用于IP地址。u_long PASCAL FAR htonl( u_long hostlong); hostlong是主機(jī)字節(jié)順序表達(dá)的32位數(shù)。htonl()返回一個(gè)網(wǎng)絡(luò)字節(jié)順序的值。(2)htons() 將主機(jī)的無(wú)符號(hào)短整型數(shù)轉(zhuǎn)換成網(wǎng)絡(luò)字節(jié)順序(Host to Network Short),用于端口號(hào)。u_short PASCAL FAR htons(
15、u_short hostshort);hostshort:主機(jī)字節(jié)順序表達(dá)的16位數(shù)。htons()返回一個(gè)網(wǎng)絡(luò)字節(jié)順序的值。 字節(jié)序轉(zhuǎn)換函數(shù)(3)ntohl()將一個(gè)無(wú)符號(hào)長(zhǎng)整型數(shù)從網(wǎng)絡(luò)字節(jié)順序轉(zhuǎn)換為主機(jī)字節(jié)順序。用于IP地址。u_long PASCAL FAR ntohl( u_long netlong); netlong是一個(gè)以網(wǎng)絡(luò)字節(jié)順序表達(dá)的32位數(shù),ntohl()返回一個(gè)以主機(jī)字節(jié)順序表達(dá)的數(shù)。(4)ntohs()將一個(gè)無(wú)符號(hào)短整型數(shù)從網(wǎng)絡(luò)字節(jié)順序轉(zhuǎn)換為主機(jī)字節(jié)順序。用于端口號(hào)u_short PASCAL FAR ntohs( u_short netshort);netshort是
16、一個(gè)以網(wǎng)絡(luò)字節(jié)順序表達(dá)的16位數(shù)。ntohs()返回一個(gè)以主機(jī)字節(jié)順序表達(dá)的數(shù)。 字節(jié)序轉(zhuǎn)換函數(shù)2獲取與套接口相連的端地址獲取與套接口相連的端地址GETPEERNAME()int getpeername( SOCKET s, struct sockaddr * name, int * namelen); 3獲取一個(gè)套接口的本地名字獲取一個(gè)套接口的本地名字GETSOCKNAME()int getsockname( SOCKET s, struct sockaddr * name, int * namelen); 4將一個(gè)點(diǎn)分十進(jìn)制形式的將一個(gè)點(diǎn)分十進(jìn)制形式的IP地址轉(zhuǎn)換成一個(gè)長(zhǎng)整型數(shù)地址轉(zhuǎn)換成一
17、個(gè)長(zhǎng)整型數(shù)INET_ADDR()unsigned long inet_addr (const char * cp); 5 將 網(wǎng) 絡(luò) 地 址 轉(zhuǎn) 換 成 點(diǎn) 分 十 進(jìn) 制 的 字 符 串 格 式 將 網(wǎng) 絡(luò) 地 址 轉(zhuǎn) 換 成 點(diǎn) 分 十 進(jìn) 制 的 字 符 串 格 式INET_NTOA()char * inet_ntoa( struct in_addr in); Winsock的信息查詢函數(shù)nGethostname()n用來(lái)返回本地計(jì)算機(jī)的標(biāo)準(zhǔn)主機(jī)名。nint gethostname(char* name, int namelen);nGethostbyname()n返回對(duì)應(yīng)于給定主機(jī)名的
18、主機(jī)信息。nstruct hostent* gethostbyname(const char* name);nGethostbyaddr()n根據(jù)一個(gè)IP地址取回相應(yīng)的主機(jī)信息。nstruct hostent* gethostbyaddr(const char* addr, int len, int type);nGetservbyname()n返回對(duì)應(yīng)于給定服務(wù)名和協(xié)議名的相關(guān)服務(wù)信息。nstruct servent* getservbyname(const char* name, const char* proto);主機(jī)名解析nGethostbynamen我們使用域名來(lái)標(biāo)識(shí)站點(diǎn),可以將文
19、字型的主機(jī)域名直接轉(zhuǎn)換成IP地址n格式:struct hostent* gethostbyname( const char* name);n入口參數(shù):是站點(diǎn)的主機(jī)域名字符串,n返回值: 是指向hostent 結(jié)構(gòu)的指針,失敗返回NULLnhostent結(jié)構(gòu)包含主機(jī)名,主機(jī)別名數(shù)組,返回地址的類型(一般是AF-INET),地址長(zhǎng)度的字節(jié)數(shù),已符合網(wǎng)絡(luò)字節(jié)順序的主機(jī)網(wǎng)絡(luò)地址等。n將轉(zhuǎn)換后的IP地址復(fù)制到服務(wù)器的地址結(jié)構(gòu)中 Winsock的信息查詢函數(shù)n除了Gethostname()函數(shù)以外,其它六個(gè)函數(shù)有以下共同的特點(diǎn):n函數(shù)名都采用GetXbyY的形式。 n如果函數(shù)成功地執(zhí)行,就返回一個(gè)指向某種
20、結(jié)構(gòu)的指針,該結(jié)構(gòu)包含所需要的信息。n如果函數(shù)執(zhí)行發(fā)生錯(cuò)誤,就返回一個(gè)空指針。應(yīng)用程序可以立即調(diào)用WSAGetLastError()來(lái)得到一個(gè)特定的錯(cuò)誤代碼。n函數(shù)執(zhí)行時(shí),可能在本地計(jì)算機(jī)上查詢,也可能通過(guò)網(wǎng)絡(luò)向域名服務(wù)器發(fā)送請(qǐng)求,來(lái)獲得所需要的信息,這取決于用戶網(wǎng)絡(luò)的配置方式。WINSOCK程序結(jié)構(gòu)n新建一個(gè)Win32 API空項(xiàng)目ninclude必需的頭文件n鏈接Winsock庫(kù)文件WS2_32.libn開(kāi)始Winsock應(yīng)用程序編程3333#include / include必需的頭文件#include #include #pragma comment(lib, Ws2_32.lib)
21、/鏈接Winsock庫(kù)文件WS2_32.libint main() /開(kāi)始Winsock應(yīng)用程序編程 return 0;不同類型套接字編程n通信方式nC/S模式與P2P模式n不同連接方式n面向連接與面向無(wú)連接n阻塞方式n阻塞模式與非阻塞模式n可以進(jìn)行組合形成不同類型的網(wǎng)絡(luò)編程面向連接的套接字工作過(guò)程 面向連接客戶機(jī)編程3636n面向連接客戶機(jī)編程步驟(阻塞模式)(1)初始化Winsock服務(wù)(2)創(chuàng)建套接字(3)主機(jī)名解析,配置套接字要訪問(wèn)的服務(wù)器的地址結(jié)構(gòu)信息(4)連接服務(wù)器(5)從服務(wù)接收信息并顯示(6)斷開(kāi)套接字連接,不允許發(fā)送數(shù)據(jù),但可以繼續(xù)接收數(shù)據(jù)(7)關(guān)閉套接字,釋放資源(8)關(guān)閉
22、Winsock服務(wù)完整的客戶機(jī)程序-(1)#include #include #pragma comment(lib,ws2_32.lib)int main()WSADATA WsaDat; / 初始化 Winsock服務(wù)if(WSAStartup(MAKEWORD(2,2),&WsaDat)!=0)std:coutWinsock錯(cuò)誤 - Winsock服務(wù)初始化失?。n;WSACleanup();system(PAUSE);return 0;SOCKET Socket=socket(AF_INET,SOCK_STREAM,0); / 創(chuàng)建套接字if(Socket=INVALID_S
23、OCKET)std:cout套接字錯(cuò)誤 -創(chuàng)建套接字失敗!rn;WSACleanup();system(PAUSE);return 0;struct hostent *host; / 主機(jī)名解析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; 完整的客戶機(jī)程序-(2) / 從服務(wù)接收
24、信息并顯示char buffer1024;memset(buffer,0,1023);int inDataLength=recv(Socket,buffer,1024,0);std:coutbuffer;/ 斷開(kāi)套接字連接,不允許發(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;完整的客戶機(jī)程序-(3)面向連接服務(wù)器編程n阻塞模式服務(wù)器編程步驟阻塞模式服務(wù)器編程步驟(1)啟動(dòng)并初始化Winsock
25、2服務(wù)(與客戶機(jī)同)(2)創(chuàng)建Socket(與客戶機(jī)同)(3)填充服務(wù)器地址、端口信息(有變化)(4)綁定服務(wù)器地址信息到套接字(新增步驟)(5)偵聽(tīng)客戶連接(新增步驟)(6)接受客戶連接(新增步驟)(7)向客戶機(jī)發(fā)送數(shù)據(jù)(8)斷開(kāi)套接字連接,停止發(fā)送數(shù)據(jù)(與客戶機(jī)同)(9)關(guān)閉套接字(與客戶機(jī)同)(10)關(guān)閉Winsock套接字服務(wù)(與客戶機(jī)同)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)建套接字失?。n;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ù)器:正在等待來(lái)自客戶機(jī)的連接.rn;TempSock=accept(Socket,NULL,NULL); So
28、cket=TempSock;std:cout服務(wù)器:有客戶機(jī)連接到達(dá)!rnrn;char *szMessage=服務(wù)器說(shuō):有朋自遠(yuǎn)方來(lái)來(lái),不亦樂(lè)乎rn;send(Socket,szMessage,strlen(szMessage),0);shutdown(Socket,SD_SEND); / 斷開(kāi)套接字連接,不允許發(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模式 有多個(gè)操作套接字
29、的系統(tǒng)調(diào)用會(huì)引起進(jìn)程阻塞。有多個(gè)操作套接字的系統(tǒng)調(diào)用會(huì)引起進(jìn)程阻塞。(1)ACCEPT()(2)READ()、RECV()和和READFORM()(3)WRITE()、SEND()和和SENDTO()(4)CONNECT()(5)SELECT()(6)CLOSESOCKET() 能引起阻塞的套接字調(diào)用 采用阻塞工作模式的單進(jìn)程服務(wù)器是不能很好采用阻塞工作模式的單進(jìn)程服務(wù)器是不能很好地同時(shí)為多個(gè)客戶服務(wù)的。地同時(shí)為多個(gè)客戶服務(wù)的。阻塞工作模式帶來(lái)的問(wèn)題非阻塞模式客戶機(jī)編程n設(shè)置套接字阻塞模式nioctlsocket(Socket,FIONBIO,&iMode); n如果設(shè)置iMode=0
30、 ,套接字將處于阻塞模式n設(shè)置iMode=1,套接字工作于非阻塞模式。n缺省狀態(tài)為阻塞模式n其他不同步驟n需要一個(gè)循環(huán)來(lái)處理數(shù)據(jù)接收過(guò)程非阻塞模式客戶機(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)/ 斷開(kāi)套接字,只能接收不能發(fā)送shutdown(Socket,SD_
31、SEND);closesocket(Socket); / 關(guān)閉套接字break;Sleep(1000);非阻塞模式服務(wù)器編程1.初始化套接字2.創(chuàng)建套接字3.配置SOCKADDR_IN地址信息4.在套接字上偵聽(tīng)5.接受來(lái)自客戶機(jī)的連接6.設(shè)置套接字工作模式nu_long iMode=1;nioctlsocket(Socket,FIONBIO,&iMode);for(;) / 主循環(huán) char *szMessage=非阻塞服務(wù)器說(shuō):有朋自遠(yuǎn)方來(lái)來(lái),不亦樂(lè)乎rn; send(Socket,szMessage,strlen(szMessage),0); int nError=WSAGetLa
32、stError(); if(nError!=WSAEWOULDBLOCK&nError!=0)std:coutWinsock錯(cuò)誤碼為: nErrorrn;std:cout客戶機(jī)斷開(kāi)連接!rn;/ 斷開(kāi)套接字連接,不允許發(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)建套接字失?。n;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ù)器:正在等待客戶機(jī)連接.rn;TempSock=accep
35、t(Socket,NULL,NULL); 非阻塞模式服務(wù)器完整代碼u_long iMode=1; / iMode!=0表示阻塞模式ioctlsocket(Socket,FIONBIO,&iMode);Socket=TempSock;std:cout服務(wù)器說(shuō):有新客戶機(jī)連接到達(dá)!rnrn;for(;) / 主循環(huán)char *szMessage=非阻塞服務(wù)器說(shuō):有朋自遠(yuǎn)方來(lái)來(lái),不亦樂(lè)乎rn;send(Socket,szMessage,strlen(szMessage),0);int nError=WSAGetLastError();if(nError!=WSAEWOULDBLOCK&
36、;nError!=0)std:coutWinsock錯(cuò)誤碼為: nErrorrn;std:cout客戶機(jī)斷開(kāi)連接!rn;shutdown(Socket,SD_SEND); / 斷開(kāi)套接字closesocket(Socket); / 關(guān)閉套接字break;Sleep(1000);5454WSAStartup()函數(shù)執(zhí)行失敗時(shí)將返回一個(gè)Winsock錯(cuò)誤碼。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ù)初始化失敗,錯(cuò)誤碼: nResultrn;WSACleanup();system(PAUSE);return 0;套接字錯(cuò)誤處理套接字錯(cuò)誤處理錯(cuò)誤處理錯(cuò)誤處理2 2:接下來(lái)的代碼是創(chuàng)建套接字,創(chuàng)建不成功怎么辦?把程序2.5中的代碼稍作如下修改即可捕獲錯(cuò)誤原因:SOCKET Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);If (Socket=INVALID_S
38、OCKET)int nError=WSAGetLastError();std:cout創(chuàng)建套接字失敗,錯(cuò)誤碼:nErrorrn;WSACleanup();system(PAUSE);return 0;套接字錯(cuò)誤處理錯(cuò)誤處理錯(cuò)誤處理3 3:成功創(chuàng)建套接字后,接下來(lái)的步驟是配置SOCKADDR_IN地址結(jié)構(gòu)信息然后進(jìn)行套接字綁定,綁定過(guò)程發(fā)生錯(cuò)誤怎么辦?if(bind(Socket,(SOCKADDR*)(&serverInf),sizeof(serverInf)=SOCKET_ERROR)int nError=WSAGetLastError();std:cout不能綁定地址信息到套接字,
39、錯(cuò)誤碼: 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ù)報(bào)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. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年跨界藝術(shù)品版權(quán)交易合同
- 2025年度智能家居瓷磚定制設(shè)計(jì)與銷售服務(wù)合同3篇
- 2024幼兒園租賃合同-附幼兒園師資培訓(xùn)及認(rèn)證服務(wù)3篇
- 2025年度打包機(jī)節(jié)能技術(shù)應(yīng)用研究與推廣合同2篇
- 2024年詩(shī)歌朗誦比賽場(chǎng)地租賃合同
- 2024年聯(lián)營(yíng)權(quán)責(zé)調(diào)整書
- 2025年度智慧社區(qū)建設(shè)合作協(xié)議書3篇
- 2024年遠(yuǎn)程醫(yī)療服務(wù)合同范本6篇
- 2024鮮花婚禮布置承包合同
- 2024年:版權(quán)與專利共享協(xié)議
- 2025年江蘇建筑安全員A證考試題庫(kù)及答案
- 2024年員工簡(jiǎn)單個(gè)人總結(jié)
- 2025屆遼寧省沈陽(yáng)市高三上學(xué)期一模英語(yǔ)試卷含答案
- 2024年南京市第一醫(yī)院分院高層次衛(wèi)技人才招聘筆試歷年參考題庫(kù)頻考點(diǎn)附帶答案
- 2025年高考?xì)v史復(fù)習(xí)之小題狂練300題(選擇題):秦漢時(shí)期(20題)
- 熱電站汽輪機(jī)發(fā)電安全操作規(guī)程(2篇)
- 2025年中考物理復(fù)習(xí)資料專題18 生活用電(知識(shí)梳理+典例+練習(xí))(原卷版)
- 2025年產(chǎn)業(yè)園區(qū)運(yùn)營(yíng)與管理企業(yè)組織結(jié)構(gòu)及部門職責(zé)
- 2024年學(xué)院宣傳工作總結(jié)(4篇)
- 福建省福州三牧中學(xué)2024-2025學(xué)年七年級(jí)上學(xué)期期中生物試題(無(wú)答案)
- 公司安全事故隱患內(nèi)部舉報(bào)、報(bào)告獎(jiǎng)勵(lì)制度
評(píng)論
0/150
提交評(píng)論