




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、第2章 Socket套接字編程套接字是由美國伯克利大學提出并設計的一種在網絡中不同主機之間進展數據交換的通信橋梁。在實際生活中,人們所使用的網絡通信軟件功能均是基于Socket套接字作為通信橋梁實現。所以,套接字在網絡編程中,有著非常重要的作用。本章將向用戶介紹使用Socket套接字編程的相關概念以及實現方法。2.1 尋址方式和字節順序在講解套接字編程前,用戶需要首先理解一下什么是尋址方式和字節順序。在Socket套接字編程中,為了準確定位通信雙方和數據傳輸的有效性、完好性,編程時必須使用統一的尋址方式和字節排列順序。2.1.1 尋址方式因為套接字需要在各種網絡協議中使用,所以為了區分程序所使
2、用的網絡協議必須使用統一的尋址方式。例如,在TCP/IP協議通信中,用戶使用IP地址和端口號進展確定通信雙方。而在其他的協議中不一定也使用該方式確定通信雙方。在WinsockSocket API中,用戶可以使用TCP/IP地址家族中統一的套接字地址構造解決TCP/IP尋址中可能出現的問題。該套接字地址構造定義如下:struct sockaddr_in short sin_family;/指定地址家族即地址格式 unsigned short sin_port;/端口號碼 struct in_addr sin_addr;/IP地址 char sin_zero8; /需要指定為0;在這個構造中,成員
3、sin_family指定使用該套接字地址的地址家族。在這里必須設置為AF_INET,表示程序所使用的地址家族是TCP/IP。注意:該構造的最后一個成員并未實際使用,主要是為了與第一個版本的套接字地址構造大小一樣而設置。在實際使用時,將這8個字節直接設為0即可。該構造成員變量sin_addr表示32位的IP地址構造。其構造定義如下: struct in_addr union struct unsigned char s_b1, s_b2,s_b3,s_b4; S_un_b;/用4個u_char字符描繪IP地址 struct unsigned short s_w1,s_w2; S_un_w;/用2
4、個u_short類型描繪IP地址 unsigned long S_addr;/用1個u_long類型描繪IP地址 S_un;通常,用戶在網絡編程中使用1個u_long類型的字符進展描繪IP地址即可。例如,使用IP地址構造in_addr 進展描繪IP地址“。代碼如下:sockaddr_in addr;addr.sin_addr.S_un.S_addr=inet_addr(218.6.132.5);在程序中,首先定義sockaddr_in構造對象addr,然后為IP地址構造in_addr中的成員S_addr賦值。因為構造成員S_addr所描繪的IP地址均為網絡字節順序,所以程序調用inet_add
5、r()函數將字符串IP轉換為以網絡字節順序排列的IP地址。2.1.2 字節順序在Socket套接字編程中,傳輸數據的排列順序以網絡字節順序和主機字節順序為主。通常情況下,假如用戶將數據通過網絡發送時,需要將數據轉換成以網絡字節順序排列,否那么可能造成數據損壞。假如用戶是將網絡中接收到的數據存儲在本地計算機上,那么需要將數據轉換成以主機字節順序排列。從數據存儲的角度來講,網絡字節順序即將數據中最重要的字節首先進展存儲,而主機字節順序那么將不重要的字節首先存儲。注意:IP地址構造in_addr中的成員S_addr的值均是以網絡字節順序排列。1字節順序轉換函數在Winsock中提供了幾個關于網絡字節
6、順序與主機字節順序之間的轉換函數。函數定義如下:/將一個u_short類型的IP地址從主機字節順序轉換到網絡字節順序u_short htons (u_short hostshort );/將一個u_long類型的IP地址從主機字節順序轉換到網絡字節順序u_long htonl (u_long hostlong );/將一個u_long類型的IP地址從網絡字節順序轉換到主機字節順序u_long ntohl (u_long netlong );/將一個u_short類型的IP地址從網絡字節順序轉換到主機字節順序u_short ntohs (u_short netshort );/將一個字符串IP轉
7、換到以網絡字節順序排列的IP地址unsigned long inet_addr (const char FAR * cp);/將一個以網絡字節順序排列的IP地址轉換為一個字符串IPchar FAR * inet_ntoa (struct in_addr in);以上函數的使用均與操作系統平臺無關。因此,用戶使用這些函數編寫的程序能在所有操作系統平臺中運行。2實例程序在本節中,將編寫實例程序向用戶講解字節順序轉換函數的用法。代碼如下:./省略部分代碼sockaddr_in addr;/定義套接字地址構造變量addr.sin_family=AF_INET;/指定地址家族為TCP/IPaddr.si
8、n_port=htons(80); /指定端口號/將字符串IP轉換為網絡字節順序排列的IPaddr.sin_addr.S_un.S_addr=inet_addr(127.0.0.1);/將網絡字節順序排列的IP轉換為字符串IPchar addres=inet_ntoa(addr.sin_addr.S_un.S_addr);在程序中,用戶首先使用函數inet_addr()將字符串IP“轉換為以網絡字節順序排列的IP并保存在IP地址構造成員S_addr中。然后,再使用函數inet_ntoa()那么將該成員所表示的IP值轉換成字符串IP。2.1.3 Socket相關函數由于Windows網絡程序開發
9、均是基于Windows套接字實現,所以本節將重點介紹MFC中的CSocket類以及使用CSocket類編程的根本流程。1創立套接字使用CSocket類創立套接字對象是通過該類的構造函數創立的。其原型如下:CSocket:CSocket( );例如,用戶創立CSocket類對象,代碼如下:CSocket sock;假如用戶需要創立套接字對象指針,那么應該使用關鍵字new進展創立。代碼如下:CSocket *sock;/定義套接字指針對象sock=new CSocket;/使用new關鍵字創立套接字2綁定地址信息假如用戶創立效勞器套接字,那么用戶應該調用該類的函數Bind()將套接字對象與效勞器地
10、址信息綁定在一起。其原型如下:BOOL Bind ( const SOCKADDR* lpSockAddr, int nSockAddrLen );該函數的作用是將套接字對象與效勞器地址構造綁定在一起。假如函數調用成功,那么返回true。否那么,返回false。參數lpSockAddr指定將要綁定的效勞器地址構造,參數nSockAddrLen表示地址構造的長度。例如,用戶將上面創立的套接字對象與地址構造綁定。代碼如下:CSocket sock;/創立套接字對象sockaddr_in addr;/定義套接字地址構造變量addr.sin_family=AF_INET;/指定地址家族為TCP/IPa
11、ddr.sin_port=htons(80);/指定端口號/將字符串IP轉換為網絡字節順序排列的IPaddr.sin_addr.S_un.S_addr=inet_addr(127.0.0.1);sock.Bind(SOCKADDR*)addr,sizeof(addr);/綁定套接字與地址構造./省略部分代碼在效勞器端,當地址信息綁定套接字成功后,還需要調用函數Listen()在指定端口監聽客戶端的連接懇求。函數Listen()的原型如下:BOOL Listen( int nConnectionBacklog = 5 );參數nConnectionBacklog表示套接字監聽客戶端懇求的最大數目
12、。該參數的有效范圍是15。默認為5,表示該套接字只能監聽5個客戶端所發送的連接懇求。例如,套接字監聽5個客戶端的連接懇求,代碼如下:CSocket sock;/創立套接字對象sockaddr_in addr;/定義套接字地址構造變量addr.sin_family=AF_INET;/指定地址家族為TCP/IPaddr.sin_port=htons(80);/指定端口號/將字符串IP轉換為網絡字節順序排列的IPaddr.sin_addr.S_un.S_addr=inet_addr(127.0.0.1);sock.Bind(SOCKADDR*)addr,sizeof(addr);/綁定套接字與地址構
13、造sock.Listen(5);/監聽端口3連接效勞器客戶端創立套接字成功以后,可以調用函數Connect()向效勞器發送連接懇求。函數原型如下:BOOL Connect( const SOCKADDR* lpSockAddr, int nSockAddrLen );該函數調用成功,那么返回true。否那么,將返回false。參數lpSockAddr表示將連接的效勞器地址構造。參數nSockAddrLen表示地址構造的長度大小。例如,效勞器IP地址為“,端口為80,客戶端連接效勞器,代碼如下:CSocket sock;/創立套接字對象sockaddr_in addr;/定義套接字地址構造變量a
14、ddr.sin_family=AF_INET;/指定地址家族為TCP/IPaddr.sin_port=htons(80);/指定端口號/將字符串IP轉換為網絡字節順序排列的IPaddr.sin_addr.S_un.S_addr=inet_addr(127.0.0.1);sock.Connect(SOCKADDR*)addr,sizeof(addr);/連接效勞器4數據交換無論是效勞器,還是客戶端都是通過函數Send()和Receive()進展數據交換。函數原型如下:virtual int Send( const void* lpBuf, int nBufLen, int nFlags = 0
15、);virtual int Receive( void* lpBuf, int nBufLen, int nFlags = 0 );其中,函數Send()用于發送指定緩沖區的數據,函數Receive()用于接收對方發送的數據,并將數據存放在指定緩沖區中。參數lpBuf表示數據緩沖區地址。參數nBufLen表示數據緩沖區的大小。參數nFlags表示數據發送或接收的標志,一般情況下,該參數均設置為0。例如,使用這兩個函數進展數據的發送和接收。代碼如下:./省略部分代碼char buff=a;/定義并初始化數據緩沖區sock.Send(&buff,sizeof(buff),0);/發送數據緩
16、沖區中的數據sock.Receive(&buff, sizeof(buff),0);/接收數據并將數據存放在數據緩沖區中5關閉套接字對象當效勞器和客戶端的通信完成以后,用戶還必須調用函數Close()將套接字對象關閉。否那么,程序可能在退出時發生錯誤。該函數原型如下:virtual void Close( );例如,客戶端關閉套接字對象,代碼如下:./省略部分代碼sock.Close();/關閉套接字對象套接字關閉的同時,也將效勞器與客戶端之間連接關閉了。本節主要向用戶介紹了CSocket類的常用函數以及用法。當用戶創立VC應用程序時,假如沒有為應用程序指定支持Windows Sock
17、et,那么用戶必須手動添加該類的頭文件。否那么,程序將不能使用CSocket類。2.2 Winsock網絡程序開發流程本節將向用戶講述基于Windows Socket的應用程序開發步驟,并將編寫實例程序向用戶介紹網絡應用程序的開發過程以及CSocket類的詳細使用方法。本節中的實例程序均在VC中進展編寫、調試。2.2.1 VC中創立工程的步驟用戶在VC中使用應用程序向導創立基于套接字的應用程序工程時,必須為該應用程序指定支持Windows Socket功能。否那么,創立的應用程序不能進展網絡通信。假如用戶創立工程工程成功,那么在應用程序向導設置的第二步,將詢問用戶是否需要在工程中支持Windo
18、ws Socket功能,如下圖。圖2.1 支持Windows Socket功能假如用戶在應用程序的第二步沒有選擇工程支持Windows Socket功能,那么在程序中手動添加代碼也可以到達同樣的目的。其代碼如下:#include /包含CSocket類的頭文件注意:頭文件中包含了CSocket類的變量以及函數定義。2.2.2 Winsock編程流程在本書的第1章中,已經向用戶介紹了Winsock函數是用于網絡編程的Windows API函數。本章在前一節中,向用戶介紹了CSocket類的根本編程流程。所以,在本節中將向用戶介紹使用Socket API函數進展網絡程序開發的根本流程與方法。1初始
19、化和釋放套接字庫由于所有的Winsock函數均是從動態鏈接庫中導出的,但是,VC在默認情況下并沒有與該庫進展連接。所以,用戶需要在VC中進展相關設置,使其連接動態庫。添加方法是選擇“Project|“Settings命令,將彈出Project Settings對話框,如下圖。圖2.2 添加動態鏈接庫用戶在工程設置對話中,可以修改或添加庫模塊如下圖。在庫模塊中添加動態鏈接庫。這樣,程序就可以調用Winsock函數了。用戶必須首先從動態鏈接庫中調用函數WSAStartup()對該庫進展初始化,之后才能從該庫中繼續正確調用其他Winsock函數。否那么,將出現錯誤。函數WSAStartup()的原型
20、如下:int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData);該函數調用成功,將返回0。否那么,調用函數失敗。參數wVersionRequested表示當前套接字庫的版本號。例如,當前套接字版本號為,那么將該參數設置為。代碼如下:WORD wVersionRequested=MAKEWORD(2,0);參數lpWSAData指向構造體WSADATA的指針變量,表示獲取到的套接字庫詳細信息。該構造體定義如下:typedef struct WSAData WORD wVersion;/庫文件建議應用程序使用的版本號 WORD wHigh
21、Version; /庫文件支持的最高版本 char szDescriptionWSADESCRIPTION_LEN+1;/描繪庫文件的字符串 char szSystemStatusWSASYS_STATUS_LEN+1;/系統狀態字符串 unsigned short iMaxSockets;/同時支持的最大套接字數 unsigned short iMaxUdpDg;/已廢棄 char FAR * lpVendorInfo;/已廢棄 WSADATA, FAR * LPWSADATA; 用戶初始化套接字庫,代碼如下:WSAData data;/定義WSAData變量WORD wVersionReq
22、uested=MAKEWORD(2,0);/定義套接字庫版本號:WSAStartup (wVersionRequested,&data);/初始化套接字庫當程序退出時,用戶還應該調用函數WSACleanup()釋放該套接字庫。代碼如下::WSACleanup();2創立套接字句柄在Socket API中,創立套接字句柄的函數是socket()。該函數原型如下:SOCKET socket ( int af,/指定套接字所使用的地址格式,在本章中只能設置為AF_INET int type, /套接字類型 int protocol /假如參數type已經指定套接字類型為TCP或UDP,那么該
23、參數可以設置為0);該函數執行成功,將返回新創立的套接字句柄。否那么,將返回INVALID_SOCKET表示失敗。參數type的取值如表所示。表2.1 套接字類型取值例如,創立流式套接字的句柄。代碼如下:SOCKET s;/定義套接字句柄s=:socket(AF_INET, SOCK_STREAM,0);/創立并返回套接字句柄 套套接字類型取值接字類型取值 含含 義義SOCK_STREAM創建流式套接字(基于創建流式套接字(基于TCP協議)協議)SOCK_DGRAM創建數據報套接字(基于創建數據報套接字(基于UDP協議)協議)SOCK_RAW創建原始套接字(本書中未使用)創建原始套接字(本書中
24、未使用)3綁定地址信息對于效勞器而言,套接字創立成功后,還應該將套接字與地址構造信息相關聯。實現這一功能的函數是bind()。該函數原型如下:int bind ( SOCKET s, /套接字句柄 const struct sockaddr FAR* name,/地址構造信息 int namelen /地址構造的大小 );該函數調用成功,那么返回0。否那么,函數調用失敗。例如,將套接字句柄綁定到本地地址,代碼如下:./省略部分代碼sockaddr_in addr;/定義套接字地址構造變量addr.sin_family=AF_INET;/指定地址家族為TCP/IPaddr.sin_port=ht
25、ons(80);/指定端口號addr.sin_addr.S_un.S_addr=INADDR_ANY /表示效勞器可以接收任何計算機發來的懇求:bind(s,(sockaddr)&addr,sizeof(addr);/綁定套接字到指定地址構造當效勞器程序將套接字句柄綁定套接字地址成功時,那么調用函數listen()實現監聽端口的功能。該函數原型如下:int listen ( SOCKET s, /實現監聽功能的套接字句柄 int backlog /指定監聽的最大連接數量 );該函數僅被用于流式套接字上。假如多個客戶端同時向效勞器發出連接懇求,并且已超過了最大監聽數,那么客戶端將返回錯誤
26、代碼。例如,程序在已創立的套接字s上進展監聽,代碼如下:./省略部分代碼:listen(s,5);/在套接字上進展監聽,并且將最大監聽數指定為54連接客戶端程序連接效勞器使用函數connect()實現。函數原型如下:int connect ( SOCKET s, /套接字句柄 const struct sockaddr FAR* name,/將要連接的效勞器地址信息構造指針 int namelen /地址信息構造體長度 );例如,客戶端使用該函數連接地址為“,端口為80的效勞器。代碼如下:sockaddr_in addr;/定義套接字地址構造變量addr.sin_family=AF_INET;
27、/指定地址家族為TCP/IPaddr.sin_port=htons(80);/指定端口號addr.sin_addr.S_un.S_addr=inet_addr(127.0.0.1);/指定效勞器地址SOCKET s;/定義套接字句柄s=:socket(AF_INET,SOCK_STREAM,0);/創立并返回套接字句柄:connect(s,( sockaddr)&addr,sizeof(addr);/連接效勞器.假如效勞器接收到客戶端的連接懇求,那么可以調用函數accept()承受該懇求。函數原型如下:SOCKET accept ( SOCKET s, /套接字句柄 struct so
28、ckaddr FAR* addr, /獲取連接對方的地址信息 int FAR* addrlen /地址長度 );該函數假如調用成功,那么返回一個新的套接字句柄,用于通信雙方數據的傳輸。5數據收發當用戶使用Winsock編程時,都是調用函數send()和recv()進展數據的發送和接收。函數原型如下:/發送數據函數int send (SOCKET s, const char FAR * buf, int len, int flags);/接收數據函數int recv (SOCKET s, char FAR* buf, int len, int flags); 兩個函數的各個參數表示的意義均一樣。
29、參數buf是指向數據緩沖區的指針變量,參數flags通常設置為0。注意:假如效勞器使用上面的函數進展數據收發,那么參數s應該為監聽函數返回的新套接字句柄。假如客戶端使用以上函數進展數據收發,那么參數s應該為客戶端創立的套接字句柄。6關閉套接字當套接字使用完畢或程序退出時,用戶應該調用函數closesocket()關閉套接字句柄。函數原型如下:int closesocket ( SOCKET s /將關閉的套接字句柄);參數s表示即將關閉的套接字句柄。例如,用戶關閉前面創立的套接字句柄s,代碼如下::closesocket(s);本節主要向用戶講述了使用Winsock函數進展程序設計的根本流程,
30、并講解了部分常用函數的用法等知識。希望用戶在實際編程的過程中,能不斷地對本節知識進展回憶,加深理解。2.2.3 基于TCP的Sockets編程在本節中,將編寫一個簡單的TCP效勞器和TCP客戶端程序。這兩個實例程序均為控制臺程序窗口。1TCP效勞器首先,在VC中新建一個基于控制臺的應用程序工程,并將該工程命名為“TCP效勞器,如下圖。圖2.3 新建控制臺應用程序然后,單擊“OK按鈕進展應用程序類型的設置。在本節中,將新建的控制臺程序類型指定為一個空工程,如下圖。圖2.4 設置空的控制臺程序用戶還需要在VC中添加一個空白的C+源文件,名稱為TCPSEVER,如下圖。圖2.5 新建C+資源文件用戶
31、在新建的C+源文件中進展代碼編寫。代碼如下:編譯并運行程序,如下圖。圖2.6 效勞器啟動界面效勞器程序啟動以后,假如沒有客戶端向其發送連接懇求,那么效勞器將一直等待直到有客戶端程序連接。2TCP客戶端在VC中創立基于控制臺的應用程序,命名為“TCP客戶端。其方法與TCP效勞器的創立過程一樣。所以,在這里不再贅述,請讀者復習前面的相關內容。在新建的C+源文件TCPClient中,用戶可以編寫客戶端的功能代碼。代碼如下:編譯并運行程序,如下圖。圖2.7 客戶端啟動界面假如用戶首先翻開效勞器程序,再翻開客戶端程序,那么效勞器會承受客戶端的連接懇求,而客戶端會顯示效勞器發送的歡送信息,如下圖。圖2.8
32、 翻開效勞器與客戶端本節向用戶講解了TCP效勞器與客戶端的通信過程,并編寫了實例代碼。用戶在學習的過程中,假如對本章實例有興趣,可以將隨書光盤中的相應的實例代碼進展改寫,以到達自己的要求。2.2.4 基于UDP的Sockets編程基于UDP的網絡程序是面向無連接,不可靠的一種應用程序。所以,當程序創立套接字句柄成功以后,便可以直接調用函數進展數據收發,最后,關閉套接字對象。在整個過程中,程序都不用調用任何函數連接效勞器或者承受客戶端的連接等操作。這種類型的應用程序多用在即時通信中。在UDP中進展數據收發的函數是sendto()和recvfrom()。函數原型如下:int sendto (/發送
33、函數 SOCKET s, /套接字句柄 const char FAR * buf,/數據緩沖區 int len,/數據的長度 int flags, /一般設置為0 const struct sockaddr FAR * to,/目的地址構造信息 int tolen /目的地址構造大小 );int recvfrom (SOCKET s, char FAR* buf, int len, int flags,struct sockaddr FAR* from, int FAR* fromlen);/接收函數函數recvfrom()的各個參數與函數sendto()的參數根本一致。參數from是指向地址
34、構造sockaddr_in的指針,表示數據發送方的地址信息。參數fromlen表示該地址構造的大小。1UDP效勞器首先,在VC中創立基于控制臺程序窗口的應用程序,并命名為“UDP效勞器,如下圖。圖2.9 新建UDP效勞器然后,將該工程類型同樣指定為空工程。在新建的工程中新建一個C+源文件,名稱為UDPSever,如下圖。圖2.10 新建C+源文件如今用戶可以在該源文件中編寫UDP效勞器的代碼。代碼如下:編譯并運行程序,如下圖。圖2.11 UDP效勞器啟動界面2UDP客戶端在VC中創立UDP客戶端程序時,與UDP效勞器一樣,工程類型均為空工程。所以,用戶只需在C+源文件中編寫代碼實現UDP客戶端
35、。代碼如下:編譯并運行程序,如下圖。圖2.12 客戶端啟動界面假如用戶先啟動UDP效勞器,再啟動UDP客戶端,那么會在效勞器界面中顯示客戶端連接信息。而客戶端界面中顯示效勞器發送的信息,如下圖。圖2.13 UDP客戶端與效勞器進展通信在本小節中,向用戶講解了在VC中使用Winsock函數進展網絡程序開發,并結合TCP與UDP實例程序介紹了基于以上兩種協議的網絡程序編寫方法。2.3 網絡程序實例應用用戶通過本章前面兩節知識的學習,已經對網絡程序的根本原理和程序編寫方法有了進一步理解。在本節中,將引導用戶在VC中編寫基于對話框的TCP效勞器和TCP客戶端程序并且進展詳細講解。2.3.1 TCP客戶
36、端程序在本小節中,將向用戶介紹在VC中創立基于對話框形式的TCP客戶端程序界面以及各個功能的實現等。1創立工程在VC中創立一個基于MFC的應用程序工程,并且將該工程名修改為“TCP客戶端程序。步驟如下:1選擇“File|“New命令,翻開“New對話框,如下圖。圖2.14 創立TCP客戶端實例工程2單擊“OK按鈕,進入應用程序向導設置的第一步,修改應用程序的類型為“Dialog based,如下圖。圖2.15 修改應用程序類型為根本對話框3單擊“Next按鈕,進入應用程序向導設置的第二步,設置應用程序支持Windows Socket的功能,如下圖。圖2.16 設置應用程序支持套接字功能4單擊“
37、Finish按鈕,完成工程的創立以及相關配置。如今,用戶通過應用程序向導已經完成了TCP客戶端工程的創立以及為該工程添加了支持Windows套接字功能等相關的一些配置。接下來,用戶需要翻開該工程的資源管理器進展程序界面的設計。2界面設計當工程創立以后,用戶可以翻開資源管理器查看該工程的對話框資源,如下圖。圖2.17 VC默認情況下的對話框資源用戶可以通過向該對話框面板中添加相應的控件,以到達TCP客戶端程序的根本功能,如下圖。圖2.18 完成設計后的界面效果其中,用戶添加了多個控件,新添加的控件ID、類型以及作用,如表所示。表2.2 控件ID、類型以及作用控件控件ID控控 件件 類類 型型控件
38、在實例中的作用控件在實例中的作用IDC_ADDR編輯框控件輸入服務器輸入服務器IP地址地址IDC_PORT編輯框控件輸入服務器端口輸入服務器端口IDC_TEXT編輯框控件顯示相關信息顯示相關信息IDC_SENDTEXT編輯框控件輸入發送消息輸入發送消息IDC_SEND按鈕控件發送消息按鈕發送消息按鈕IDC_CONNECT按鈕控件連接服務器連接服務器IDC_STATIC1靜態控件標識服務器地址標識服務器地址IDC_STATIC2靜態控件靜態控件標識服務器端口標識服務器端口3界面初始化TCP客戶端程序啟動時,應該首先連接效勞器以后,用戶才能通過程序發送消息。所以,該程序初始化時的界面,如下圖。圖2
39、.19 程序初始化界面在界面初始化時,已經屏蔽了發送消息的功能。所以對于應用程序而言,防止了錯誤的發生。初始化代碼如下:用戶使用函數GetDlgItem()獲取對應ID控件的指針,然后使用該指針調用函數EnableWindow()將控件禁用。函數EnableWindow()的參數假如為true,那么表示該控件可以被使用。假如該參數為false,那么表示該控件被禁用。在界面初始化時,除了初始化界面中的各按鈕之外,還應該對套接字進展初始化。初始化套接字功能的代碼應該在函數CTCPDlg:OnInitDialog()中實現。代碼如下:在代碼中,用戶在類中聲明了套接字對象和套接字地址構造變量。然后,在
40、初始化函數中創立了TCP套接字s。4功能實現在這一節中,用戶可以為各個功能控件編寫相應的代碼,以實現其功能。首先,為“連接按鈕添加消息響應函數。在該控件上雙擊鼠標,將彈出Add Member Function添加成員函數對話框,如下圖。圖 添加成員函數對話框在該對話框中,用戶可以將“連接按鈕的消息響應函數名修改為OnConnect()。函數代碼如下:將上面的代碼保存以后,進展編譯并運行。假如客戶端連接效勞器成功,那么程序會提示用戶連接成功,如下圖。圖 客戶端連接效勞器成功否那么,程序提示用戶連接效勞器失敗,如下圖。圖2.22 客戶端連接效勞器失敗當客戶端與效勞器連接成功之后,用戶便可以發送消息
41、到效勞器了。如今,用戶需要為“發送按鈕添加相應的消息響應函數,并指定該函數名為OnSend()。該函數相關代碼如下:在代碼中,用戶通過調用函數send()將消息發送到指定的效勞器,并將該消息顯示在本地的信息顯示框中,如下圖。圖 客戶端發送消息作為客戶端,還應該具有接收并顯示效勞器所發送的消息。在本實例中,將采用異步套接字形式實現該功能。在VC中,將套接字設置為異步形式,可以調用函數WSAAsyncSelect()實現。該函數原型如下:int WSAAsyncSelect ( SOCKET s, HWND hWnd, unsigned int wMsg, long lEvent );函數各個參數
42、如下:參數s表示需要設置為異步形式的套接字句柄。參數hWnd表示接收消息響應的窗口句柄。參數wMsg表示響應消息標識。參數lEvent表示發生在該套接字上的事件,取值如表所示。表 套接字事件部分標識及其意義套接字事件取值套接字事件取值含含 義義 表表 示示套接字事件取值套接字事件取值含含 義義 表表 示示FD_READ套接字上發生讀取事件FD_ACCEPT套接字上發生連接事件套接字上發生連接事件FD_WRITE套接字上發生寫入事件套接字上發生寫入事件FD_CLOSE套接字上發生關閉事件套接字上發生關閉事件首先,在程序初始化函數OnInitDialog中,將套接字設置為異步形式。代碼如下:代碼中
43、,將異步套接字處理的事件指定為讀取事件FD_READ,并且將該事件的處理消息指定為WM_SOCKET。該消息是在CTCPDlg類頭文件中定義的自定義消息。代碼如下:用戶自定義消息以及該消息的響應函數成功后,還需要在消息映射表中將消息與響應函數相關聯。代碼如下:最后,在自定義消息響應函數OnSocket()中,實現套接字事件的處理。代碼如下:由于在本實例中,僅處理了套接字的讀取事件,所以使用了代碼“if(lParam= FD_READ)。假如用戶需要處理的套接字事件比較多,那么應該在代碼中使用關鍵字switch進展分類判斷。程序運行效果如下圖。圖2.24 程序運行效果到這里,用戶根本上完成了客戶
44、端應有的功能。在客戶端程序中,需要用戶注意連接效勞器之前,必須首先知道效勞器的IP地址等相關信息。否那么,程序將無法正確連接到效勞器。2.3.2 TCP效勞器程序在節中,已經向用戶講解了制作TCP客戶端程序的相關方法。所以,在本節中將向用戶繼續講解在VC中怎樣制作TCP效勞器程序。1創立工程在VC中,創立TCP效勞器工程的步驟與創立TCP客戶端工程的步驟一樣,只是在修改工程名稱時應該為“TCP效勞器程序,如下圖。圖2.25 創立TCP效勞器程序工程其他相關設置步驟均與TCP客戶端工程的設置步驟一樣。所以,在本章中不再對此內容進展講述,請用戶復習上一節中的內容。注意:用戶在VC中創立實例工程的步驟大體一樣。2界面設計效勞器工程創立完成之后,用戶可以翻開資源管理器中的對話框資源進展界面的設計。本實例中,為了完成效勞器的根本功能,所以在對話框面板上添加如表所示的控件,并調整其位置以及大小。表 控件ID、屬性以及作用用戶將表中所示控件添加到對話框面板中后,應
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年物流管理專業理論知識考試試題及答案
- 2025年社區工作者職稱考試試題及答案
- 2025年社會心理學師職稱考試試題及答案
- 2025年教師資格證考試題及答案
- 2025年法律職業資格考試題及答案
- 2025年城市管理與服務能力考試題及答案
- 2024年度浙江省護師類之主管護師能力提升試卷A卷附答案
- 2024年度浙江省二級注冊建筑師之法律法規經濟與施工通關試題庫(有答案)
- 2024年度浙江省二級造價工程師之土建建設工程計量與計價實務模擬題庫及答案下載
- 實驗室監督人員培訓
- 2024-2025學年廣東人教版高一英語第二學期期末練習卷(含答案)
- 中南大學《論文寫作與學術道德》2021-2022學年第一學期期末試卷
- 勞動法課件(完整版)
- 營運車輛智能視頻監控系統管理制度范本及動態監控管理制度
- 偏頭痛PPT課件(PPT 43頁)
- (完整版)入河排污口設置論證基本要求
- 10kV架空線路施工方案
- 2022年人教版小學數學一年級下冊期中測試卷二(含答案)
- 關于恒溫恒濕項目裝修方案及裝修細部做法
- 機器學習簡介PPT通用課件
- 《鐵路建設項目施工圖審核管理辦法》2022年299號-最新
評論
0/150
提交評論