?? 14.6.2 客戶端程序.txt
字號:
14.6.2 客戶端程序
下面編寫基于UDP的聊天客戶端程序,同樣,向己有的NetSrv工作區中增加一個空的 Windows32
Console Application類型的工程: NetClient。并為該工程添加一個C++源文件: NetClient.cpp。
接著,為該工程添加對WinSock庫的鏈接,即在工程設置對話框的Link選項卡上添加ws2 32.lib
文件的鏈接。然后在NetClient叩p文件中添加聊天客戶端程序的實現代碼,結果如例 14-6所示。
~JJ 14-6
#include <W工nsock2 .h> #include <stdio .h>
飛Toid main ()
//加載套接字庫
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData ) ; i f ( err ! = 0 ) {
554
'如'
return,
if ( LOBYTE( wsaData.wVersion ) != 1 II
H工 BYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( ),
return,
11創建套接字
SOCKET sockClient=socket(AF_INET, SOCK_DGRAM, O) ,
SOCKADDR_IN addrSrv, addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1") ,
addrSrv.sin_family=AF_INET, addrSrv.sin-port=htons(6000) ,
char recvBuf[100] ,
char sendBuf[100] ,
char tempBuf[200] ,
int len=sizeof.(SOCKADDR) ,
while (1)
11發送數據
printf("Please input data:\n") ,
gets (sendBu f) ,
sendto(sockClient , sendBuf , strlen(sendBuf) +1 , 0 ,
(SOCKADDR*)&addrSrv, len);
/1等待并接收數據
recvfrom(sockClient , recvBuf , 100 , O, (SOCKADDR*)&addrSrv, &len) ,
if('q'==recvBuf[O])
{ sendto (sockClient , "q" , strlen ( "q" ) +1 , 0 ,
(SOCKADDR*)&addrSrv, len) , printf("Chat end!\n" ) , break,
}
sprintf (tempBuf , "氈 s say :革 s", inet_ntoa(addrSrv.sin_addr), recvBuf),
printf("氈 s\n", tempBuf) ,
11關閉套接字
closesocket(sockClient) ,
WSACleanup() ,
'~.‘ I 555
在上述例 14-6所示代碼中,首先加載套接字庫,這可以復制上面程序中己有的代碼。
然后,按照上面講述的基于UDP(面向無連接)的socket編程的客戶端程序的編寫過程,第一步應
該調用socket函數創建套接字,其參數設置與上面NetSrv程序中的相同。
對基于 UDP的客戶端程序來說,它不需要綁定,但它需要設定數據發送的目標方的地址信息,實
際上就是將數據發送到服務器端,于是定義-個地址變量: addrS凹,并將該變量中的字段設定為
服務器端的地址信息。因為在本例中,服務器端和客戶端程序都是在本機上運行,所以IP地址還
是選用 127.0.0.1,然后利用iElet-addr函數將點分十進制格式的IP地址轉換為u_long類型的數
值。
接下來,定義了三個字符數組,其中recvBuf用來保存接收的信息; sendBuf用來保存發送的信息;
tempBuf用來存放中間臨時數據。
因為在調用recvfrom函數接收數據時,該函數的最后一個參數將接收返回的地址結構的長度,但
是在調用之前這個參數變量必須經過初始化,因此,定義一個整型變量: len. 并將其初始化為
地址結構類型SOCKADDR的長度。
然后,程序進行一個while循環。在該循環中,作為數據發送端來說,首先要發送數據,并且要
發送的數據是用戶通過鍵盤輸入的。于是程序首先提示用戶讓其輸入數據,然后調用gets函數獲
取用戶輸入的數據。得到數據后,就可以調用sendto函數發送數據。
在發送完數據之后,接下來就等待服務器端的回應信息,于是調用recv企om函數。同樣地,在接
收到數據之后,判斷服務器端是否想要退出,即接收到的第一個字符是否是"q"字符,如果是,
表明服務器端想要退出,則也發送一個"q"字符,并且多發送一個字節,之后,打印信息: Chat
end!,表明聊天終止,然后調用break語句終止while循環。如務器端發送來的數據第一個字符不
是字符 "q",則把服務器端困復的信息進行格式化,然后打印在標準輸出設備,即屏幕上。格式
化的模式是:服務器端IP say服務器端回復的數據,其中服務器端E地址可以通過變量addrSrv的
sin_addr字段獲得,然后調用inecntoa函數將in_addr結構類型的數據轉換為點分十進制格式表
示的E地址字符串。
當退出while循環后,需要調用closesocket函數關閉套接字,并調用WSACleanup函數終止套接字
庫的使用。以上就是基于 UDP的簡單網絡聊天程序的客戶端的實現。利用 Bui1d命令生成
NetClient程序。
這時,.基于 UDP的簡單網絡聊夭程序的服務器端和客戶端程序都已經生成了,可以看看效果。
首先啟動服務器端,然后啟動客戶端,接著在客戶端輸入 "hel1o",并按回車鍵,然后就可以看
到服務器端收到了: "127.0.0.1 say: Hel1o"這條信息。這時,后者也可以輸入 "hello",并按
回車鍵,客戶端會立即收到服務器端的回應信息。服務器端和客戶端可以繼續按此方式聊天。當
某一端不想再繼續聊天時,可以輸入 "q"字符并回車,于是可以看到雙方的聊天過程終止了。
這里我們實現了一個簡單的基于~UDP的網絡聊天程序,后面的章節還會介紹一個基
于圖形界面的采用多線程技術實現的網絡聊天程序。
556 I ~~...
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -