版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、第2章 Socket編程接口楊 明紫金學(xué)院計(jì)算機(jī)系網(wǎng)絡(luò)編程2022-4-29內(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、的事實(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ù),來解除與Winsock.DLL庫的綁定,釋放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)聽連接-listen函數(shù)n接受連接-accept函數(shù)n斷開套接字-shutdown函數(shù)n關(guān)閉套接字-closesocket函數(shù)創(chuàng)建套接字nsocket()nsocket過程創(chuàng)建一個(gè)套接字并返回一個(gè)整型描述符n格式:int SOCKET( int Protofamily, int Type, int Protocol); n參數(shù)1: 說明使用協(xié)議簇,對(duì)于IPv4,設(shè)置為AF_INETn參數(shù)2:說明套接字類型,如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)的長度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)的長度。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僅用于客戶端,用來請(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)聽nlisten()n告訴服務(wù)器端套接字開始監(jiān)聽客戶機(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)長度。nstruct sockaddr_in cltsockaddr; / 定義返回客戶端地址的結(jié)構(gòu)nclientfd=ACCEPT(listenfd, (sockaddr* )(&cltsockaddr), &addrlen); / 接收客戶連接請(qǐng)求 斷開與關(guān)閉套接字n斷開套接字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() 長整數(shù)本機(jī)順序轉(zhuǎn)換為網(wǎng)絡(luò)順序,用于IP地址。
14、nntohs() 短整數(shù)網(wǎng)絡(luò)順序轉(zhuǎn)換為本機(jī)順序,用于端口號(hào)。nntohl() 長整數(shù)網(wǎng)絡(luò)順序轉(zhuǎn)化為本機(jī)順序,用于IP地址。(1)htonl() 將主機(jī)的無符號(hào)長整型數(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ī)的無符號(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è)無符號(hào)長整型數(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è)無符號(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è)長整型數(shù)地址轉(zhuǎn)換成一
17、個(gè)長整型數(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用來返回本地計(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我們使用域名來標(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),地址長度的字節(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()來得到一個(gè)特定的錯(cuò)誤代碼。n函數(shù)執(zhí)行時(shí),可能在本地計(jì)算機(jī)上查詢,也可能通過網(wǎng)絡(luò)向域名服務(wù)器發(fā)送請(qǐng)求,來獲得所需要的信息,這取決于用戶網(wǎng)絡(luò)的配置方式。WINSOCK程序結(jié)構(gòu)n新建一個(gè)Win32 API空項(xiàng)目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可以進(jìn)行組合形成不同類型的網(wǎng)絡(luò)編程面向連接的套接字工作過程 面向連接客戶機(jī)編程3636n面向連接客戶機(jī)編程步驟(阻塞模式)(1)初始化Winsock服務(wù)(2)創(chuàng)建套接字(3)主機(jī)名解析,配置套接字要訪問的服務(wù)器的地址結(jié)構(gòu)信息(4)連接服務(wù)器(5)從服務(wù)接收信息并顯示(6)斷開套接字連接,不允許發(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ù)初始化失??!rn;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;/ 斷開套接字連接,不允許發(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)偵聽客戶連接(新增步驟)(6)接受客戶連接(新增步驟)(7)向客戶機(jī)發(fā)送數(shù)據(jù)(8)斷開套接字連接,停止發(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)建套接字失??!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ù)器:正在等待來自客戶機(jī)的連接.rn;TempSock=accept(Socket,NULL,NULL); So
28、cket=TempSock;std:cout服務(wù)器:有客戶機(jī)連接到達(dá)!rnrn;char *szMessage=服務(wù)器說:有朋自遠(yuǎn)方來來,不亦樂乎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模式 有多個(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ù)的。阻塞工作模式帶來的問題非阻塞模式客戶機(jī)編程n設(shè)置套接字阻塞模式nioctlsocket(Socket,FIONBIO,&iMode); n如果設(shè)置iMode=0
30、 ,套接字將處于阻塞模式n設(shè)置iMode=1,套接字工作于非阻塞模式。n缺省狀態(tài)為阻塞模式n其他不同步驟n需要一個(gè)循環(huán)來處理數(shù)據(jù)接收過程非阻塞模式客戶機(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.接受來自客戶機(jī)的連接6.設(shè)置套接字工作模式nu_long iMode=1;nioctlsocket(Socket,FIONBIO,&iMode);for(;) / 主循環(huán) char *szMessage=非阻塞服務(wù)器說:有朋自遠(yuǎn)方來來,不亦樂乎rn; send(Socket,szMessage,strlen(szMessage),0); int nError=WSAGetLa
32、stError(); if(nError!=WSAEWOULDBLOCK&nError!=0)std:coutWinsock錯(cuò)誤碼為: nErrorrn;std:cout客戶機(jī)斷開連接!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ù)器:正在等待客戶機(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ù)器說:有新客戶機(jī)連接到達(dá)!rnrn;for(;) / 主循環(huán)char *szMessage=非阻塞服務(wù)器說:有朋自遠(yuǎn)方來來,不亦樂乎rn;send(Socket,szMessage,strlen(szMessage),0);int nError=WSAGetLastError();if(nError!=WSAEWOULDBLOCK&
36、;nError!=0)std:coutWinsock錯(cuò)誤碼為: nErrorrn;std:cout客戶機(jī)斷開連接!rn;shutdown(Socket,SD_SEND); / 斷開套接字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:接下來的代碼是創(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)建套接字后,接下來的步驟是配置SOCKADDR_IN地址結(jié)構(gòu)信息然后進(jìn)行套接字綁定,綁定過程發(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. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(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至2030年中國連接器插針件行業(yè)投資前景及策略咨詢研究報(bào)告
- 2024至2030年中國電動(dòng)車專用無線遙控防盜報(bào)警器行業(yè)投資前景及策略咨詢研究報(bào)告
- 2024至2030年中國什錦海鮮湯餃行業(yè)投資前景及策略咨詢研究報(bào)告
- 2024至2030年多用途純天然樟腦精油項(xiàng)目投資價(jià)值分析報(bào)告
- 2024至2030年串珠磁管項(xiàng)目投資價(jià)值分析報(bào)告
- 2024至2030年鮮橙醬項(xiàng)目投資價(jià)值分析報(bào)告
- 薦2024年度商業(yè)連鎖經(jīng)營承包合同范本
- 2024年度三人合伙經(jīng)營酒店旅游業(yè)合同
- 2024版城市地鐵發(fā)傳單運(yùn)營合同范本6篇
- 2024版租房合同涉及的保險(xiǎn)條款3篇
- 2024版小學(xué)科學(xué)六年級(jí)上冊第四單元《能量》教學(xué)課件
- TSHZSAQS 00255-2024 食葵病蟲害防治技術(shù)規(guī)范
- 2024農(nóng)村機(jī)井轉(zhuǎn)讓合同范本
- 2024年院前急救護(hù)士理論考核參考題庫(含各題型)
- 2025屆江蘇省蘇州市吳中學(xué)、吳江、相城區(qū)數(shù)學(xué)八上期末綜合測試試題含解析
- 2024-2030年中國巨菌草市場需求規(guī)模及未來發(fā)展戰(zhàn)略研究報(bào)告
- 人教版高一上學(xué)期化學(xué)(必修一)《第四章物質(zhì)結(jié)構(gòu)元素周期律》單元測試卷-帶答案
- 2024至2030年中國文具市場發(fā)展預(yù)測及投資策略分析報(bào)告
- 水利工程承包人常用的表格(51個(gè))
- 專題01:基礎(chǔ)知識(shí)綜合(解析版)-2022-2023學(xué)年七年級(jí)語文下學(xué)期期中專題復(fù)習(xí)(江蘇專用)
- 日結(jié)工協(xié)議書日結(jié)工用工協(xié)議
評(píng)論
0/150
提交評(píng)論