對MFC封裝Windows通訊API的研究

發表于:2007-07-14來源:作者:點擊數: 標簽:
一、引言 Inte .net 進行網際間通訊,在WWW瀏覽、FTP、Gopher這些常規服務,以及在 網絡 電話、多媒體會議等這些對實時性要求嚴格的應用中成為研究的熱點,而且已經是必需的了。 Windows 環境下進行通訊程序設計的最基本方法是應用WindowsSockets實現進程間的
一、引言
     Inte.net進行網際間通訊,在WWW瀏覽、FTP、Gopher這些常規服務,以及在網絡電話、多媒體會議等這些對實時性要求嚴格的應用中成為研究的熱點,而且已經是必需的了。Windows環境下進行通訊程序設計的最基本方法是應用WindowsSockets實現進程間的通訊,為此微軟提供了大量基于WindowsSockets的通訊API,如WinSockAPI、WinInetAPI和ISAPI,并一直致力于開發更快、更容易的通訊API,將其和MFC集成在一起以使通訊編程越來越容易。
   MFC是VC編程環境最重要的組成部分,它為用戶提供了一大批預先定義的類和成員函數,封裝了大量的WindowsAPI。同時VC環境提供了與MFC對象和代碼一起工作的專用工具:AppStudio源程序編輯器、AppWizard和ClassWizard。應用MFC,可以使Windows程序員用較少的時間和精力開發出復雜的通訊應用程序。

   本文根據筆者自己在開發實時網絡音頻工具FreeTalk過程中的一些經驗,介紹Windows環境下的常用API和封裝它們的MFC類,重點介紹使用MFC的CAsyncsocket和CSocket類編寫網絡通訊程序的方法,這兩個類封裝了WinSockAPI,并使他們更容易使用和更適應于MFC編程環境。

二、Windows環境下的通訊API和相應的MFC類
   1.WindowsSockets(WinSock)API
   WindowsSockets定義了Windows的網絡編程接口,它基于加利福尼亞大學伯克利分校的伯克利UnixSockets。WindowsSockets既包括BSD風格的例程,還加入了Windows的擴展部分,例如用于消息驅動的擴展函數。WindowsSockets可以運行在許多網絡協議之上,包括TCP/IP、XNS、DECNet、IPX/SPX等。在Win32環境下,WindowsSockets提供線程安全。通過微軟與標準組織的努力,為WinSock定義了應用程序設計接口(WinSockAPI),可以非常方便地利用下層的網絡協議(如TCP/IP)進行網絡通訊。

    通過提供兩個類CAsyncSocket和CSocket,MFC支持使用WinSockAPI通訊程序設計。MFC把復雜的WinSockAPI封裝到類里,這使得編寫應用程序更容易。CAsyncSocket類逐個封裝了WinSockAPI,為高級網絡程序員提供了更加有力而靈活的方法。這個類基于程序員了解網絡通訊的假設,目的是為了在MFC中使用WinSock,程序員有責任處理諸如阻塞、字節順序和在Unicode與MBCS間轉換字符的任務。為了給程序員提供更方便的接口以自動處理這些任務,MFC給出了CSocket類,這個類是由CAsyncSocket類繼承下來的,它提供了比CAsyncSocket更高層的WinSockAPI接口。Csocket類和CsocketFile類與Carchive類一起合作來管理發送和接收的數據,這使管理數據收發更加便利。CSocket對象提供阻塞模式,這對于Carchive的同步操作是至關重要的。阻塞函數[比如Receive()、Send()、ReceiveFrom()、SendTo()和Aclearcase/" target="_blank" >ccept()]直到操作完成后才返回控制權,因此如果需要低層控制和高效率,就使用CasyncSock類;如果需要方便,則可使用Csocket類。2.Win32Internet(WinInet)API

    微軟公布了一些使Internet應用程序的設計比以前更快、更容易的API:WinInetAPI,它提供了中高層通信函數,這使訪問主要的Internet協議變得相當容易。這些函數在程序員和WinSock驅動之間提供了隔離層。有4類WinInetAPI函數:通用WinInet函數、WinInet文件傳輸協議(FTP)函數、WinInetGopher函數、WinInet超文本傳輸協議(HTTP)函數。

    事實上,MFC把WinInetAPI和ActiveX技術封裝進類,使Internet編程更加容易,這些類包括CInternetSession、CInternetConnection、CInternetFile、CHttpConnection、CHttpFile、CGopherFile、CFtpConnection、CGopherConnection、CFileFind、CFtpFileFind、CGopherFileFind、CGopherLocator和CInternetException。

    3.Internet服務器API(ISAPI)

    微軟的IIS是惟一與WindowsNTServer操作系統緊密集成的WWW服務器,它作為Internet/Intranet服務器應用范圍很廣。IIS允許擴展功能,這是通過ISAPI來實現的,ISAPI描述了與Internet服務器之間的接口。用ISAPI提供的工具,可建立高性能、高效率、滿足商業安全及符合新的IIS標準的Internet服務器。同樣,ISAPI在MFC中由典型的類所封裝,包括CHttpFilter、CHttpFilterContext、CHttpServer、CHttpServerContext、RelatedClasses和CHtmlStream。

三、WinSockAPI的MFC封裝類
    一些網絡應用程序(如網絡電話、多媒體會議工具)實時性要求非常強,要求能夠直接應用WinSock發送和接收數據。這時設計者應該選擇直接應用WinSockAPI或者由MFC封裝的WinSockAPI。新開發的應用程序中,為了充分利用MFC的優勢,首選方案應當是MFC中的CAsyncSocket類和CSocket類,這兩個類完全封裝了WinSockAPI,并提供更多的便利。本文介紹應用這兩個類的編程模型,并引出相關的成員函數與一些概念的解釋。
    1.CAsyncSocket類和CSocket類簡述
    CAsyncSocket類和CSocket類的繼承關系由附圖給出。CSocket類是由CAsyncSocket繼承而來的,事實上,在MFC中CAsyncSocket逐個封裝了WinSockAPI,每個CAsyncSocket對象代表一個WindowsSocket,使用CAsyncSocket類要求程序員對網絡編程較為熟悉。相比起來,CSocket類是CAsyncSocket的派生類,繼承了它封裝的WinSockAPI。一個CSocket對象代表了一個比CAsyncSocket對象更高層次的WindowsSocket抽象,CSocket類與CSocketFile類和CArchive類一起工作來發送和接收數據,因此使用它更加容易。CSocket對象提供阻塞模式,因為阻塞功能對于CArchive的同步操作是至關重要的。在這里有必要對阻塞的概念作一解釋:一個socket可以處于“阻塞模式”或“非阻塞模式”,當一個套接字處于阻塞模式(即同步操作)時,它的阻塞函數直到操作完成才會返回控制權,之所以稱為阻塞是因為此套接字的阻塞函數在完成操作返回之前什么也不能做。如果一個socket處于非阻塞模式(即異步操作),則會被調用函數立即返回。在CAsyncSocket類中可以用GetLastError成員函數查詢最后的錯誤,如果錯誤是WSAEWOULDBLOCK則說明有阻塞,而CSocket絕不會返回WSAEWOULDBLOCK,因為它自己管理阻塞。微軟建議盡量使用非阻塞模式,通過網絡事件的發生而通知應用程序進行相應的處理。但在CSocket類中,為了利用CArchive處理通訊中的許多問題和簡化編程,它的一些成員函數總是具有阻塞性質的,這是因為CArchive類需要同步的操作。在Win32環境下,如果要使用具有阻塞性質的套接字,應該放在獨立的工人線程中處理,利用多線程的方法使阻塞不至于干擾其他線程,也不會把CPU時間浪費在阻塞上。多線程的方法既可以使程序員享受CSocket帶來的簡化編程的便利,也不會影響用戶界面對用戶的反應。

    2.CAsyncsocket類編程模型

    在一個MFC應用程序中,要想輕松處理多個網絡協議,而又不犧牲靈活性時,可以考慮使用CAsyncSocket類,它的效率比CSocket類要高。CAsyncSocket類針對字節流型套接字的編程模型簡述如下:

    (1)構造一個CAsyncSocket對象,并用這個對象的Create成員函數產生一個Socket句柄??梢园慈缦聝煞N方法構造:

CAsyncSocketsock;
Sock.Create();
file://使用默認參數產生一個字節流套接字

CAsyncSocket*pSocket=newCAsyncSocket;
intnPort=27;
pSocket->Create(nPort,SOCK-DGRAM);
file://指定端口號產生一個數據報套接字

    第一種方法在棧上產生一個CAsyncSocket對象,而第二種方法在堆上產生CAsyncSocket對象。第一種Create成員函數用缺省參數產生一個字節流套接字,第二種Create成員函數用指定的端口和地址產生一個數字報套接字。Create的參數有:
    ①端口,UINT類型。注意:如果是服務方,則使用一個眾所周知的端口供服務方連接;如果是客戶方,典型做法是接受默認參數,使套接字可以自主選擇一個可用端口;

    ②socket類型。SOCK-STREAM(默認值)或SOCK-DGRAM;

    ③socket地址。例如“ftp.gliet.edu.cn”或“202.193.64.33”。

    (2)如是客戶方程序,用CAsyncSocket∷Connect成員函數連接到服務方;如是服務方程序,用CAsyncSocket∷Listen成員函數開始監聽,一旦收到連接請求,則調用CAsyncSocket∷Accept成員函數開始接收。注意:CAsyncSocket∷Accept成員函數要用一個新的并且是空的CSocket對象作為它的參數,這里所說的“空的”指的是這個新對象還沒有調用Create成員函數。

    (3)調用其他的CAsyncSocket類成員函數進行通訊管理。

    (4)通訊結束后,銷毀CAsyncSocket對象。如果是在棧上產生的CAsyncSocket對象,則對象超出定義的范圍時自動被析構;如果是在堆上產生,也就是用了new這個操作符,則必須使用delete操作符銷毀CAsyncSocket對象。

    3.CSocket類編程模型

    使用CSocket對象涉及CArchive和CSocketFile類對象。以下介紹的針對字節流型套接字的操作步驟中,只有第3步對于客戶方和服務方操作是不同的,其他步驟都相同。

    (1)構造一個CSocket對象。

    (2)使用這個對象的Create成員函數產生一個socket句柄。在客戶方程序中,除非需要數據報套接字,Create一般情況下應該使用默認參數。而對于服務方程序,必須在調用Create時指定一個端口。注意:CArchive不能與數據報(UDP)套接字一起工作,因此對于數據報套接字,CAsyncSocket和CSocket的使用方法是一樣的。

    (3)如果是客戶方套接字,則調用CAsyncSocket∷Connect與服務方套接字連接;如果是服務方套接字,則調用CAsyncSocket∷Listen開始監聽來自客戶方的連接請求,收到連接請求后,調用CAsyncSocket∷Accept接受請求,建立連接。注意:Accept成員函數需要一個新的并且為空的CSocket對象作為它的參數,解釋同上。

    (4)產生一個CSocketFile對象,并把它與CSocket對象關聯起來。

    (5)為接收和發送數據各產生一個CArchive對象,把它們與CSocketFile對象關聯起來。切記CArchive是不能和數據報套接字一起工作的。

    (6)使用CArchive對象在客戶與服務方傳送數據。(7)通訊完畢后,銷毀CArchive、CSocketFile和CSocket對象。

原文轉自:http://www.anti-gravitydesign.com

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97