青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

春暖花開
雪化了,花開了,春天來了
posts - 149,comments - 125,trackbacks - 0
轉(zhuǎn): 異步非阻塞套接字Winsock開發(fā)網(wǎng)絡(luò)通信程序的經(jīng)典入門
摘自: http://hi.baidu.com/mcu%5Fspaces/blog/item/aee07a66ed816323ab184cdf.html

對(duì)于許多初學(xué)者來說,網(wǎng)絡(luò)通信程序的開發(fā),普遍的一個(gè)現(xiàn)象就是覺得難以入手。許多概念,諸如:同步(Sync)/異步(Async),阻塞(Block)/非阻塞(Unblock)等,初學(xué)者往往迷惑不清,只知其所以而不知起所以然。


  異步方式指的是發(fā)送方不等接收方響應(yīng),便接著發(fā)下個(gè)數(shù)據(jù)包的通信方式;而同步指發(fā)送方發(fā)出數(shù)據(jù)后,等收到接收方發(fā)回的響應(yīng),才發(fā)下一個(gè)數(shù)據(jù)包的通信方式。

  阻塞套接字是指執(zhí)行此套接字的網(wǎng)絡(luò)調(diào)用時(shí),直到成功才返回,否則一直阻塞在此網(wǎng)絡(luò)調(diào)用上,比如調(diào)用recv()函數(shù)讀取網(wǎng)絡(luò)緩沖區(qū)中的數(shù)據(jù),如果沒有數(shù)據(jù)到達(dá),將一直掛在recv()這個(gè)函數(shù)調(diào)用上,直到讀到一些數(shù)據(jù),此函數(shù)調(diào)用才返回;而非阻塞套接字是指執(zhí)行此套接字的網(wǎng)絡(luò)調(diào)用時(shí),不管是否執(zhí)行成功,都立即返回。比如調(diào)用recv()函數(shù)讀取網(wǎng)絡(luò)緩沖區(qū)中數(shù)據(jù),不管是否讀到數(shù)據(jù)都立即返回,而不會(huì)一直掛在此函數(shù)調(diào)用上。在實(shí)際Windows網(wǎng)絡(luò)通信軟件開發(fā)中,異步非阻塞套接字是用的最多的。平常所說的C/S(客戶端/服務(wù)器)結(jié)構(gòu)的軟件就是異步非阻塞模式的。

  對(duì)于這些概念,初學(xué)者的理解也許只能似是而非,我將用一個(gè)最簡(jiǎn)單的例子說明異步非阻塞Socket的基本原理和工作機(jī)制。目的是讓初學(xué)者不僅對(duì)Socket異步非阻塞的概念有個(gè)非常透徹的理解,而且也給他們提供一個(gè)用Socket開發(fā)網(wǎng)絡(luò)通信應(yīng)用程序的快速入門方法。操作系統(tǒng)是Windows 98(或NT4.0),開發(fā)工具是Visual C++6.0。

  MFC提供了一個(gè)異步類CAsyncSocket,它封裝了異步、非阻塞Socket的基本功能,用它做常用的網(wǎng)絡(luò)通信軟件很方便。但它屏蔽了Socket的異步、非阻塞等概念,開發(fā)人員無需了解異步、非阻塞Socket的原理和工作機(jī)制。因此,建議初學(xué)者學(xué)習(xí)編網(wǎng)絡(luò)通信程序時(shí),暫且不要用MFC提供的類,而先用Winsock2     API,這樣有助于對(duì)異步、非阻塞Socket編程機(jī)制的理解。

  為了簡(jiǎn)單起見,服務(wù)器端和客戶端的應(yīng)用程序均是基于MFC的標(biāo)準(zhǔn)對(duì)話框,網(wǎng)絡(luò)通信部分基于Winsock2 API實(shí)現(xiàn)。
  先做服務(wù)器端應(yīng)用程序。
  用MFC向?qū)ё鲆粋€(gè)基于對(duì)話框的應(yīng)用程序SocketSever,注意第三步中不要選上Windwos Sockets選項(xiàng)。在做好工程后,創(chuàng)建一個(gè)SeverSock,將它設(shè)置為異步非阻塞模式,并為它注冊(cè)各種網(wǎng)絡(luò)異步事件,然后與自定義的網(wǎng)絡(luò)異步事件聯(lián)系上,最后還要將它設(shè)置為監(jiān)聽模式。在自定義的網(wǎng)絡(luò)異步事件的回調(diào)函數(shù)中,你可以得到各種網(wǎng)絡(luò)異步事件,根據(jù)它們的類型,做不同的處理。下面將詳細(xì)介紹如何編寫相關(guān)代碼。
  在SocketSeverDlg.h文件的類定義之前增加如下定義:

#define     NETWORK_EVENT     WM_USER+166     file://定義網(wǎng)絡(luò)事件
   
SOCKET ServerSock; file://服務(wù)器端Socket
在類定義中增加如下定義:
class CSocketSeverDlg : CDialog
{
public:
       SOCKET ClientSock[CLNT_MAX_NUM]; file://存儲(chǔ)與客戶端通信的Socket的數(shù)組

       /*各種網(wǎng)絡(luò)異步事件的處理函數(shù)*/
       void OnClose(SOCKET CurSock);      file://對(duì)端Socket斷開
       void OnSend(SOCKET CurSock);      file://發(fā)送網(wǎng)絡(luò)數(shù)據(jù)包
       void OnReceive(SOCKET CurSock); file://網(wǎng)絡(luò)數(shù)據(jù)包到達(dá)
       void OnAccept(SOCKET CurSock);     file://客戶端連接請(qǐng)求

       BOOL InitNetwork();     file://初始化網(wǎng)絡(luò)函數(shù)
       void OnNetEvent(WPARAM wParam, LPARAM lParam); file://異步事件回調(diào)函數(shù)
                   …
};
        
在SocketSeverDlg.cpp文件中增加消息映射,其中OnNetEvent是異步事件回調(diào)函數(shù)名:
       ON_MESSAGE(NETWORK_EVENT,OnNetEvent)
定義初始化網(wǎng)絡(luò)函數(shù),在SocketSeverDlg.cpp文件的OnInitDialog()中調(diào)此函數(shù)即可。
BOOL CSocketSeverDlg::InitNetwork()
{
       WSADATA wsaData;

       //初始化TCP協(xié)議
       BOOL ret = WSAStartup(MAKEWORD(2,2), &wsaData);
       if(ret != 0)
       {
           MessageBox('初始化網(wǎng)絡(luò)協(xié)議失敗!');
           return FALSE;
       }

       //創(chuàng)建服務(wù)器端套接字
       ServerSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
       if(ServerSock == INVALID_SOCKET)
       {
           MessageBox('創(chuàng)建套接字失敗!');
           closesocket(ServerSock);
           WSACleanup();
           return FALSE;
       }

       //綁定到本地一個(gè)端口上
       sockaddr_in localaddr;
       localaddr.sin_family = AF_INET;
       localaddr.sin_port = htons(8888);     //端口號(hào)不要與其他應(yīng)用程序沖突
       localaddr.sin_addr.s_addr = 0;
       if(bind(ServerSock ,(struct sockaddr*)&localaddr,sizeof(sockaddr))
                                             = = SOCKET_ERROR)
       {
           MessageBox('綁定地址失敗!');
           closesocket(ServerSock);
           WSACleanup();
           return FALSE;
       }

       //將SeverSock設(shè)置為異步非阻塞模式,并為它注冊(cè)各種網(wǎng)絡(luò)異步事件,其中m_hWnd      
       //為應(yīng)用程序的主對(duì)話框或主窗口的句柄
       if(WSAAsyncSelect(ServerSock, m_hWnd, NETWORK_EVENT, FD_ACCEPT | FD_CLOSE | FD_READ | FD_WRITE) == SOCKET_ERROR)
       {
           MessageBox('注冊(cè)網(wǎng)絡(luò)異步事件失敗!');
           WSACleanup();
           return FALSE;
       }
       listen(ServerSock, 5); file://設(shè)置偵聽模式
       return TRUE;
}

下面定義網(wǎng)絡(luò)異步事件的回調(diào)函數(shù)
void CSocketSeverDlg::OnNetEvent(WPARAM wParam, LPARAM lParam)
{
       //調(diào)用Winsock API函數(shù),得到網(wǎng)絡(luò)事件類型
       int iEvent = WSAGETSELECTEVENT(lParam);

       //調(diào)用Winsock API函數(shù),得到發(fā)生此事件的客戶端套接字
       SOCKET CurSock= (SOCKET)wParam;

       switch(iEvent)
       {
           case FD_ACCEPT:         //客戶端連接請(qǐng)求事件
               OnAccept(CurSock);
               break;
           case FD_CLOSE:          //客戶端斷開事件:
               OnClose(CurSock);
               break;
           case FD_READ:           //網(wǎng)絡(luò)數(shù)據(jù)包到達(dá)事件
               OnReceive(CurSock);
               break;
            case FD_WRITE:         //發(fā)送網(wǎng)絡(luò)數(shù)據(jù)事件
               OnSend(CurSock);
               break;
            default: break;
        }
}
   

  以下是發(fā)生在相應(yīng)Socket上的各種網(wǎng)絡(luò)異步事件的處理函數(shù),其中OnAccept傳進(jìn)來的參數(shù)是服務(wù)器端創(chuàng)建的套接字,OnClose()、OnReceive()和OnSend()傳進(jìn)來的參數(shù)均是服務(wù)器端在接受客戶端連接時(shí)新創(chuàng)建的用與此客戶端通信的Socket。
void CSocketSeverDlg::OnAccept(SOCKET CurSock)
{
       //接受連接請(qǐng)求,并保存與發(fā)起連接請(qǐng)求的客戶端進(jìn)行通信Socket
       //為新的socket注冊(cè)異步事件,注意沒有Accept事件
}

void CSocketSeverDlg::OnClose(SOCET CurSock)
{
       //結(jié)束與相應(yīng)的客戶端的通信,釋放相應(yīng)資源
}

void CSocketSeverDlg::OnSend(SOCET CurSock)
{
       //在給客戶端發(fā)數(shù)據(jù)時(shí)做相關(guān)預(yù)處理
}

void CSocketSeverDlg::OnReceive(SOCET CurSock)
{
       //讀出網(wǎng)絡(luò)緩沖區(qū)中的數(shù)據(jù)包
}       

       
  用同樣的方法建立一個(gè)客戶端應(yīng)用程序。初始化網(wǎng)絡(luò)部分,不需要將套接字設(shè)置為監(jiān)聽模式。注冊(cè)異步事件時(shí),沒有FD_ACCEPT,但增加了FD_CONNECT事件,因此沒有OnAccept()函數(shù),但增加了OnConnect()函數(shù)。向服務(wù)器發(fā)出連接請(qǐng)求時(shí),使用connect()函數(shù),連接成功后,會(huì)響應(yīng)到OnConnect()函數(shù)中。下面是OnConnect()函數(shù)的定義,傳進(jìn)來的參數(shù)是客戶端Socket和服務(wù)器端發(fā)回來的連接是否成功的標(biāo)志。
void CSocketClntDlg::OnConnect(SOCKET CurSock, int error)
{
       if(0 = = error)
       {
           if(CurSock = = ClntSock)
           MessageBox('連接服務(wù)器成功!');
       }
}

  定義OnReceive()函數(shù),處理網(wǎng)絡(luò)數(shù)據(jù)到達(dá)事件;
  定義OnSend()函數(shù),處理發(fā)送網(wǎng)絡(luò)數(shù)據(jù)事件;
  定義OnClose()函數(shù),處理服務(wù)器的關(guān)閉事件。
            
  以上就是用基于Windows消息機(jī)制的異步I/O模型做服務(wù)器和客戶端應(yīng)用程序的基本方法。另外還可以用事件模型、重疊模型或完成端口模型,讀者可以參考有關(guān)書籍。
  在實(shí)現(xiàn)了上面的例子后,你將對(duì)Winsock編網(wǎng)絡(luò)通信程序的機(jī)制有了一定的了解。接下來你可以進(jìn)行更精彩的編程, 不僅可以在網(wǎng)上傳輸普通數(shù)據(jù),而且還以傳輸語(yǔ)音、視頻數(shù)據(jù),你還可以自己做一個(gè)網(wǎng)絡(luò)資源共享的服務(wù)器軟件,和你的同學(xué)在實(shí)驗(yàn)室的局域網(wǎng)里可以共同分享你的成果。

 

 

同步服務(wù)器套接字掛起應(yīng)用程序的執(zhí)行,直到套接字上接收到連接請(qǐng)求。同步服務(wù)器套接字不適用于在操作中大量使用網(wǎng)絡(luò)的應(yīng)用程序,但它們可能適用于簡(jiǎn)單的網(wǎng)絡(luò)應(yīng)用程序。使用 BindListen 方法設(shè)置 Socket 以在終結(jié)點(diǎn)上偵聽之后,Socket 就可以隨時(shí)使用 Accept 方法接受傳入的連接請(qǐng)求了。應(yīng)用程序被掛起,直到調(diào)用 Accept 方法時(shí)接收到連接請(qǐng)求。

接收到連接請(qǐng)求時(shí),Accept 返回一個(gè)與連接客戶端關(guān)聯(lián)的新 Socket 實(shí)例。下面的示例讀取客戶端數(shù)據(jù),在控制臺(tái)上顯示該數(shù)據(jù),然后將該數(shù)據(jù)回顯到客戶端。Socket 不指定任何消息協(xié)議,因此字符串“<EOF>”標(biāo)記消息數(shù)據(jù)的結(jié)尾。它假定一個(gè)名為 listener 的 Socket 已初始化,并綁定到一個(gè)終結(jié)點(diǎn)。

Console.WriteLine("Waiting for a connection...");
Socket handler = listener.Accept();
String data = null;

while (true) {
     bytes = new byte[1024];
     int bytesRec = handler.Receive(bytes);
     data += Encoding.ASCII.GetString(bytes,0,bytesRec);
     if (data.IndexOf("<EOF>") > -1) {
         break;
     }
}

Console.WriteLine( "Text received : {0}", data);

byte[] msg = Encoding.ASCII.GetBytes(data);
handler.Send(msg);
handler.Shutdown(SocketShutdown.Both);
handler.Close();

msdn官方說明:http://msdn2.microsoft.com/zh-cn/library/80z2essb(VS.80).aspx

posted on 2009-07-16 15:56 Sandy 閱讀(2317) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 網(wǎng)絡(luò)學(xué)習(xí)Windows Mobile
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲视频欧美在线| 欧美日韩国产bt| 亚洲一区欧美二区| 久久久五月天| 欧美综合国产精品久久丁香| 欧美精品黄色| 亚洲成人资源网| 国产欧美一区二区三区另类精品| 最近中文字幕日韩精品| 一区二区三区在线看| 亚洲欧美在线一区二区| 亚洲制服av| 欧美精品99| 亚洲国产精品成人精品| 亚洲韩日在线| 久久亚洲精品欧美| 女女同性女同一区二区三区91| 国产亚洲一级| 欧美在线网站| 狂野欧美激情性xxxx欧美| 国产日韩欧美一区在线 | 亚洲欧美日韩综合aⅴ视频| 欧美激情va永久在线播放| 欧美成人日本| 亚洲精品一二三区| 欧美韩国日本综合| 亚洲日韩欧美视频一区| 亚洲美女在线观看| 欧美日韩一区精品| 亚洲精品一区在线| 亚洲色在线视频| 国产精品你懂的在线欣赏| 亚洲一区二区黄| 久久精品国产亚洲aⅴ| 国产偷自视频区视频一区二区| 午夜激情一区| 老司机一区二区三区| 精品999成人| 欧美电影美腿模特1979在线看| 亚洲国产小视频| 亚洲在线免费观看| 国产视频精品xxxx| 久久亚洲精品中文字幕冲田杏梨| 欧美大片一区二区| 在线天堂一区av电影| 国产精品手机视频| 久久久亚洲高清| 亚洲激情中文1区| 午夜影视日本亚洲欧洲精品| 国产午夜精品全部视频在线播放 | 永久555www成人免费| 欧美sm视频| 亚洲一级片在线看| 免费中文日韩| 午夜国产不卡在线观看视频| 国内精品国语自产拍在线观看| 美乳少妇欧美精品| 亚洲一区欧美激情| 欧美顶级少妇做爰| 亚洲一区二区在线免费观看视频| 国产日韩一区二区三区在线播放| 久久综合九色综合欧美狠狠| 亚洲全黄一级网站| 久久久国产精品亚洲一区| 亚洲精品视频一区| 国产香蕉97碰碰久久人人| 欧美成人tv| 欧美在线免费| 宅男精品视频| 亚洲福利久久| 久久精品视频一| 国产精品99久久不卡二区| 很黄很黄激情成人| 国产精品乱人伦中文| 欧美成人精品| 久久精品一二三| 亚洲欧美日韩国产成人精品影院| 亚洲电影自拍| 免费国产自线拍一欧美视频| 欧美一区亚洲一区| 在线一区欧美| 亚洲精品一区在线观看香蕉| 国内精品国产成人| 国产欧美日韩综合一区在线播放 | 性久久久久久久| 一区二区三区精密机械公司 | 亚洲女ⅴideoshd黑人| 亚洲精选成人| 亚洲国产精品ⅴa在线观看 | 亚洲国产1区| 国产午夜精品视频| 国产精品自拍网站| 国产精品毛片a∨一区二区三区| 欧美电影在线播放| 久久伊人免费视频| 久久亚洲精品视频| 久久久久国产精品一区三寸| 欧美亚洲自偷自偷| 午夜久久电影网| 西西人体一区二区| 欧美一级在线亚洲天堂| 午夜欧美不卡精品aaaaa| 亚洲一区二区成人在线观看| 99综合精品| 亚洲视频在线观看视频| 一本大道久久a久久精二百| 亚洲免费观看| 国产精品99久久久久久www| 一区二区免费在线视频| 亚洲视频在线看| 亚洲免费视频一区二区| 亚洲综合视频1区| 欧美一级艳片视频免费观看| 欧美呦呦网站| 久久综合国产精品| 欧美激情一区二区三区高清视频| 欧美xxx在线观看| 欧美精选午夜久久久乱码6080| 欧美国产亚洲另类动漫| 欧美激情一区在线| 国产精品草草| 国产日韩在线一区| 亚洲成在人线av| 亚洲每日更新| 午夜视频在线观看一区| 久久国产精品毛片| 欧美成人精品在线| 日韩视频一区二区三区在线播放 | 亚洲国产三级在线| 亚洲精品久久视频| 亚洲一区二区在线观看视频| 欧美综合激情网| 免费在线一区二区| 国产精品久久久久aaaa樱花| 国产视频自拍一区| 91久久精品国产| 亚洲综合精品一区二区| 久久米奇亚洲| 亚洲精品影院| 欧美在线一二三四区| 欧美a级片网站| 国产精品美女主播| 亚洲韩国日本中文字幕| 亚洲欧美一级二级三级| 蜜臀av国产精品久久久久| 亚洲精选成人| 久久久久久999| 国产精品高清网站| 亚洲人成网站在线播| 午夜日韩激情| 亚洲欧洲一区| 久久久久久9| 国产精品一区免费在线观看| 91久久在线| 久久精品视频在线观看| 亚洲六月丁香色婷婷综合久久| 久久成人这里只有精品| 国产精品99免视看9| 亚洲国产精品ⅴa在线观看| 午夜视频一区二区| 亚洲精品一区二区三区四区高清 | 欧美日韩国产999| 精品成人在线| 欧美一区二区三区久久精品| 最新国产乱人伦偷精品免费网站| 午夜免费在线观看精品视频| 欧美日韩一区精品| 亚洲黄页一区| 美女视频网站黄色亚洲| 亚洲欧美日韩综合国产aⅴ| 欧美日韩精品一区二区三区| 在线看片日韩| 狂野欧美激情性xxxx| 亚洲一区二区三区在线视频| 欧美精品在线免费| 亚洲国产高清自拍| 毛片av中文字幕一区二区| 午夜视频一区在线观看| 国产精品国产一区二区| 亚洲一区二区三区在线看| 亚洲伦理在线免费看| 欧美国产一区视频在线观看| 在线精品视频免费观看| 老司机aⅴ在线精品导航| 久久成人免费| 精品69视频一区二区三区| 久久久久久亚洲精品中文字幕 | 在线亚洲一区二区| 欧美日本亚洲视频| 99精品国产一区二区青青牛奶| 欧美激情一区二区在线| 久久综合影视| 亚洲精品美女在线观看播放| 欧美成人亚洲成人| 欧美插天视频在线播放| 亚洲三级免费电影| 亚洲精品一区二区在线观看| 欧美日韩精品在线视频| 亚洲视屏一区| 午夜久久美女|