• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看

      ?

      應(yīng)用SOCKET實(shí)現(xiàn)網(wǎng)絡(luò)通信

      2012-02-14 14:57:26李光明
      通信電源技術(shù) 2012年3期
      關(guān)鍵詞:IP地址應(yīng)用程序端口

      李光明

      (西安政治學(xué)院,陜西 西安710068)

      0 引 言

      衛(wèi)星遙測(cè)數(shù)據(jù)處理系統(tǒng)是基于C/S的體系結(jié)構(gòu),分為遙測(cè)參數(shù)處理軟件和遙測(cè)參數(shù)處理結(jié)果顯示軟件,兩個(gè)軟件模塊可在同一機(jī)器上或不同機(jī)器上獨(dú)立運(yùn)行,通過SOCKET鏈路交換數(shù)據(jù),實(shí)時(shí)接收有效載荷管理工作站中的遙測(cè)數(shù)據(jù),完成實(shí)時(shí)處理。處理結(jié)果實(shí)時(shí)回送有效載荷管理工作站進(jìn)行入庫處理,同時(shí)以組廣播的形式向所有的顯示工作站實(shí)時(shí)傳送數(shù)據(jù),供監(jiān)視衛(wèi)星運(yùn)行情況。本文將詳細(xì)討論這項(xiàng)技術(shù),同時(shí)列舉出筆者在SOCKET編程過程中的幾點(diǎn)經(jīng)驗(yàn)。

      1 SOCKET編程的基本概念

      Windows NT提供了一個(gè)最重要的通信程序設(shè)計(jì)機(jī)制——Windows Sockets(WinSock),使我們?cè)诰W(wǎng)絡(luò)通信編程上有很大的發(fā)揮空間。

      一個(gè)套接字(Socket)是一個(gè)通信端點(diǎn)。典型的通信發(fā)生于一個(gè)客戶和一個(gè)服務(wù)器之間,就有兩個(gè)端點(diǎn),一個(gè)在客戶端,一個(gè)在服務(wù)器端。對(duì)應(yīng)的就有兩個(gè)套接字,且這兩個(gè)套接字在客戶和服務(wù)器之間建立了雙向數(shù)據(jù)傳送的連接。

      套接字基本上分為兩類:流套接字、數(shù)據(jù)報(bào)套接字。流套接字(Stream Sockets)用于大流量數(shù)據(jù)的雙向傳輸,數(shù)據(jù)流可分為記錄流或字節(jié)流,這取決于協(xié)議。流通常用于無重復(fù)(UnDuplicated)的和順序(Sequenced,保持包發(fā)送順序)的傳送和接收數(shù)據(jù)。流套接字保證數(shù)據(jù)發(fā)送。數(shù)據(jù)報(bào)套接字(Datagram Sockets)主要用于廣播功能。數(shù)據(jù)報(bào)套接字支持雙向數(shù)據(jù)流,不保證可靠、有序、無重復(fù)性,是面向無連接的傳輸機(jī)制。

      套接字應(yīng)用程序可以使用一個(gè)端口(port)與其它套接字應(yīng)用程序通信。端口的含義可以這樣理解:它的作用是可以實(shí)現(xiàn)在具有一個(gè)IP地址的單臺(tái)機(jī)器上同時(shí)有效地運(yùn)行多個(gè)客戶或演示軟件,各個(gè)到達(dá)的TCP包或UDP包都被指定給某一特定的端口。例如,可以在一個(gè)窗口中執(zhí)行FTP,同時(shí)在另一個(gè)窗口運(yùn)行自己的套接字應(yīng)用程序或其它通信程序,確保不同通信程序的數(shù)據(jù)不被混淆在一起的機(jī)制就是端口。公用通信功能使用保留端口,用戶可指定未被保留且未被使用的端口,或傳遞0作為端口值由Sockets自動(dòng)分配端口。

      每個(gè)套接字還有一個(gè)套接字地址,通常是應(yīng)用程序運(yùn)行所在計(jì)算機(jī)的IP地址。

      Socket實(shí)際上代表了IP地址和端口號(hào)的組合,變成了通信中一種抽象化的終端節(jié)點(diǎn)。

      套接字通信通常分為三個(gè)階段:

      (1)執(zhí)行安裝功能。創(chuàng)建并綁定一個(gè)套接字,定位并與遠(yuǎn)程計(jì)算機(jī)建立一個(gè)套接字連接。

      (2)發(fā)送和接收數(shù)據(jù)。若正在編寫一個(gè)服務(wù)類型的套接字應(yīng)用程序,則可創(chuàng)建一個(gè)套接字并監(jiān)聽從客戶來的套接字連接輸入。若有多個(gè)用戶想同步的建立連接,則可請(qǐng)求積壓連接請(qǐng)求。

      (3)執(zhí)行清除功能。斷開和關(guān)閉套接字連接。

      與其它的Windows程序設(shè)計(jì)領(lǐng)域一樣,可用API或MFC庫對(duì)Windows Sockets編程。WinSock使用TCP/IP協(xié)議,但TCP/IP并不是 WinSock支持的唯一協(xié)議,它還支持 Novell的IPX/SPX、Digital的DECNet和除TCP/IP之外的其它協(xié)議。在TCP/IP協(xié)議組中,TCP是一種面向連接的協(xié)議,為用戶提供可靠的、全雙工的字節(jié)流服務(wù),具有確認(rèn)、流控制、多路復(fù)用和同步等功能,適于數(shù)據(jù)傳輸。而UDP協(xié)議則是無連接的,每個(gè)分組都攜帶完整的目的地址,各分組在系統(tǒng)中獨(dú)立傳送。它不能保證分組的先后順序,不進(jìn)行分組出錯(cuò)的恢復(fù)與重傳,因此不能保證傳輸?shù)目煽啃裕?,它提供高傳輸效率的?shù)據(jù)報(bào)服務(wù),適于實(shí)時(shí)的語音、圖像傳輸、廣播消息等網(wǎng)絡(luò)傳輸。

      本文主要以 MFC下 Windows Sockets編程為例,介紹一般使用方法及注意事項(xiàng)。

      2 編程基本流程

      MFC下提供兩種SOCKET類型供用戶使用:SOCK_STREAM、SOCK_DGRAM,相應(yīng)有兩種類CasyncSocket、Csocket可供使用。

      Csocket封裝的socket使用TCP協(xié)議,提供有序的、可靠的、雙向的、連接的、無重復(fù)并且無記錄邊界的比特流傳輸機(jī)制。CasyncSocket封裝的socket使用UDP協(xié)議,支持雙向數(shù)據(jù)流,但并不保證是可靠、有序、無重復(fù)的,為面向無連接的數(shù)據(jù)報(bào)傳輸機(jī)制。

      MFC下客戶和服務(wù)器利用面向連接的Csocket進(jìn)行通信的過程、具體編程細(xì)節(jié)參考MFC下Chatter、Chatsrvr程序示例。

      一般來說,客戶方在OnReceive()中處理數(shù)據(jù),服務(wù)器方在監(jiān)聽Socket的OnAccept()中處理客戶連接,并在其中建立數(shù)據(jù)處理Socket,數(shù)據(jù)處理Socket在OnReceive()中處理數(shù)據(jù)。

      客戶和服務(wù)器利用CasyncSocket進(jìn)行通信的過程,UDP協(xié)議下的通信較簡(jiǎn)單,不需要事先建立連接,而是通過數(shù)據(jù)定向發(fā)送、接收實(shí)現(xiàn)服務(wù)器/客戶通信。

      3 編程點(diǎn)滴

      3.1 SOCKET創(chuàng)建

      3.1.1 一般過程

      以MFC下異步SOCKET創(chuàng)建為例:

      (1)首先聲明SOCKET對(duì)象

      CAsyncSocket socket。

      (2)創(chuàng)建SOCKET

      socket.Create(UINT nSocketPort = 0,int nSocketType=SOCK_DGRAM,long lEvent= FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT|FD_CLOSE,LPCTSTR lpszSocketAddress=NULL);

      其中,nSocketPort是此socket綁定的端口號(hào),區(qū)分不同的應(yīng)用程序;nSocketType是socket類型,此處應(yīng)用UDP協(xié)議,選用數(shù)據(jù)報(bào)類型;lEvent指明此socket需要反應(yīng)的消息,可重載相應(yīng)的消息映射函數(shù)做出動(dòng)作。

      下面的討論主要針對(duì)nSocketPort、lpszSocket-Address兩個(gè)參數(shù)的指定,為敘述簡(jiǎn)便,標(biāo)識(shí)nSocket-Port為端口,標(biāo)識(shí)lpszSocketAddress為IP地址。記住,使用該類進(jìn)行socket創(chuàng)建后,不要再調(diào)用bind()函數(shù),因?yàn)镸FC的CasyncSocket類已經(jīng)將socket的create()和bind()封裝在一起,形成Create()。

      3.1.2 注意事項(xiàng)

      (1)在同一計(jì)算機(jī)、同一應(yīng)用程序中創(chuàng)建兩個(gè)CAsyncSocket:socket1、socket2

      a.socket1、socket2不能指定同一端口、同一地址;

      b.socket1、socket2指定相同端口、但地址必須不同;

      c.socket1、socket2指定相同地址、但端口必須不同;

      d.若socket1調(diào)用Create()創(chuàng)建,指明端口,但未指明IP地址。則socket1的IP地址不能再改變,除非它是已連接的或I/O正在產(chǎn)生,否則得不到地址;socket2不能指定該端口、指定本機(jī)任一IP地址創(chuàng)建;socket2可以更換端口、指定本機(jī)任一IP地址創(chuàng)建;socket2可以更換端口、不指定IP地址創(chuàng)建。

      (2)創(chuàng)建一個(gè)CAsyncSocket:socket

      不要試圖嘗試以任何方式再次創(chuàng)建同一個(gè)socket,任何方式指端口、IP地址的組合方式,即:

      不能以相同端口、不同IP地址再次創(chuàng)建該socket;

      不能以相同端口、相同IP地址再次創(chuàng)建該socket;

      不能以不同端口、相同IP地址再次創(chuàng)建該socket;

      不能以不同端口、不同IP地址再次創(chuàng)建該socket。

      3.2 組廣播SOCKET的建立

      組廣播通信可以實(shí)現(xiàn)一臺(tái)或多臺(tái)機(jī)器向網(wǎng)絡(luò)中的多臺(tái)機(jī)器發(fā)送數(shù)據(jù)信息,且這種方式對(duì)發(fā)送端來說編程簡(jiǎn)潔,通過向一個(gè)單一組地址發(fā)送來實(shí)現(xiàn)點(diǎn)對(duì)多點(diǎn)通信。

      3.2.1 組廣播通信原理

      TCP/IP協(xié)議地址分配中的D類地址即為多目地址(multicast address),范圍是224.0.0.0~239.255.255.255。組廣播通信雙方認(rèn)知一個(gè)D類地址中的組廣播地址,發(fā)送數(shù)據(jù)向目的端口。該地址發(fā)送數(shù)據(jù),接收數(shù)據(jù)方將本機(jī)IP地址加入該組地址中,并在該端口上建立SOCKET等待數(shù)據(jù)接收。數(shù)據(jù)以廣播方式發(fā)送到各臺(tái)聯(lián)網(wǎng)計(jì)算機(jī),由協(xié)議判斷該由哪臺(tái)計(jì)算機(jī)接收數(shù)據(jù),判斷的依據(jù)就是本機(jī)IP地址與組廣播地址的關(guān)系。

      3.2.2 組廣播實(shí)現(xiàn)

      組廣播SOCKET的建立涉及到SOCKET屬性的設(shè)置,即函數(shù)

      int setsockopt (SOCKET s,int level,int optname,const char FAR * optval,int optlen)

      設(shè)置了SOCKET的屬性,創(chuàng)建組SOCKET時(shí),level設(shè)置為IPPROTO_IP,optname設(shè)置為IP_ADD_M(jìn)EMBERSHIP,optval類型為struct ip_mreq,組地址和本機(jī)地址就在該結(jié)構(gòu)中指定,下面具體給出實(shí)例,函數(shù)和結(jié)構(gòu)的具體信息可查VC幫助。

      //接收方加入組地址實(shí)例

      CAsyncSocket Socket; //聲明異步SOCKET

      Socket.Create(5000,SOCK_DGRAM); //以端口5000,缺省地址創(chuàng)建SOCKET

      struct ip_mreq bindGroup; //聲明結(jié)構(gòu)

      bindGroup.imr_multiaddr.s_addr=inet_addr(“232.20.1.1”); //填充組地址

      bindGroup.imr_interface.s_addr=inet_addr(“10.3.17.13”); //填充本機(jī)地址

      //設(shè)置SOCKET屬性

      int status= setsockopt(Socket->m_h(yuǎn)Socket,IPPROTO_IP,

      IP_ADD_M(jìn)EMBERSHIP,

      (char*)&bindGroup,sizeof(struct ip_mreq));

      if(status==SOCKET_ERROR)//出錯(cuò)處理

      int err= GetLastError();

      CString mes;

      mes.Format("Add Group Failed,Error Code:%d.",err);

      MessageBox(mes);

      3.3 Winsock的編程特點(diǎn)與異步選擇機(jī)制

      3.3.1 阻塞及其處理方式

      在網(wǎng)絡(luò)通訊中,由于網(wǎng)絡(luò)擁擠或一次發(fā)送的數(shù)據(jù)量過大等原因,經(jīng)常會(huì)發(fā)生交換的數(shù)據(jù)在短時(shí)間內(nèi)不能傳送完,收發(fā)數(shù)據(jù)的函數(shù)因此不能返回,這種現(xiàn)象叫做阻塞。Winsock對(duì)有可能阻塞的函數(shù)提供了兩種處理方式:阻塞和非阻塞方式。在阻塞方式下,收發(fā)數(shù)據(jù)的函數(shù)在被調(diào)用后一直要到傳送完畢或者出錯(cuò)才能返回。在阻塞期間,被阻的函數(shù)不斷會(huì)調(diào)用系統(tǒng)函數(shù)GetMessage()來保持消息循環(huán)的正常進(jìn)行。對(duì)于非阻塞方式,函數(shù)被調(diào)用后立即返回,當(dāng)傳送完成后由Winsock給程序發(fā)一個(gè)事先約定好的消息。

      編程時(shí)應(yīng)盡量使用非阻塞方式。因?yàn)樵谧枞绞较?,用戶可能?huì)長(zhǎng)時(shí)間的等待過程中試圖關(guān)閉程序,因?yàn)橄⒀h(huán)還在起作用,所以程序的窗口可能被關(guān)閉。這樣當(dāng)函數(shù)從Winsock的動(dòng)態(tài)連接庫中返回時(shí),主程序已經(jīng)從內(nèi)存中刪除,這顯然是極其危險(xiǎn)的。

      3.3.2 異步選擇函數(shù) WSAAsyncSelect()的使用

      Winsock通過WSAAsyncSelect()自動(dòng)地設(shè)置套接字處于非阻塞方式。使用 Windows Sockets實(shí)現(xiàn)Windows網(wǎng)絡(luò)程序設(shè)計(jì)的關(guān)鍵就是它提供了對(duì)網(wǎng)絡(luò)事件基于消息的異步存取,用于注冊(cè)應(yīng)用程序感興趣的網(wǎng)絡(luò)事件。它請(qǐng)求 Windows Sockets DLL在檢測(cè)到套接字上發(fā)生的網(wǎng)絡(luò)事件時(shí),向窗口發(fā)送一個(gè)消息。對(duì)UDP協(xié)議,這些網(wǎng)絡(luò)事件主要為:

      FD_READ期望在套接字收到數(shù)據(jù)(即讀準(zhǔn)備好)時(shí)接收通知;

      FD_WRITE期望在套接字可發(fā)送數(shù)(即寫準(zhǔn)備好)時(shí)接收通知;

      FD_CLOSE期望在套接字關(guān)閉時(shí)接電通知;消息變量wParam指示發(fā)生網(wǎng)絡(luò)事件的套接字,變量1Param的低字節(jié)描述發(fā)生的網(wǎng)絡(luò)事件,高字包含錯(cuò)誤碼。如在窗口函數(shù)的消息循環(huán)中均加一個(gè)分支:

      int ok=sizeof(SOCKADDR);

      case wMsg;

      switch(1Param)

      case FD_READ://套接字上讀數(shù)據(jù)

      if(recvfrom(sr.lpPlayData[j],dwDataSize,0,(struct sockaddr FAR*)&there1,

      (int FAR*)&ok)==SOCKET_ERROR0

      MessageBox}hwnd,“數(shù)據(jù)接收失??!”,“”,MB_OK);

      return(FALSE);

      case FD_WRITE://套接字上寫數(shù)據(jù)

      break;

      在程序的編制中,應(yīng)根據(jù)需要靈活地將WSAAsyncSelect()函數(shù)放在相應(yīng)的消息循環(huán)之中。同時(shí),按照程序容錯(cuò)誤設(shè)計(jì),應(yīng)建立一個(gè)專門的容錯(cuò)處理函數(shù)。程序中可能出現(xiàn)的各種錯(cuò)誤都將由該函數(shù)進(jìn)行處理,依據(jù)錯(cuò)誤的危害程度不同,建立幾種不同的處理措施。這樣,才能保證雙方通信的順利和可靠。

      [1] [美]Douglas E Comer.Internet Working with TCP/IP[M].北京:電子工業(yè)出版社,1998.

      [2] 蔣東興.Windows Sockets網(wǎng)絡(luò)程序設(shè)計(jì)大全[M].北京:清華大學(xué)出版社,1999.

      [3] [美]Kate Gregory.Visual C++5開發(fā)使用手冊(cè)[M].北京:機(jī)械工業(yè)出版社,1998.

      [4] [美]Robert D Thompson.MFC開發(fā)人員參考手冊(cè)[M].前導(dǎo)工作室,1998.

      猜你喜歡
      IP地址應(yīng)用程序端口
      一種端口故障的解決方案
      鐵路遠(yuǎn)動(dòng)系統(tǒng)幾種組網(wǎng)方式IP地址的申請(qǐng)和設(shè)置
      刪除Win10中自帶的應(yīng)用程序
      端口阻塞與優(yōu)先級(jí)
      基于SNMP的IP地址管理系統(tǒng)開發(fā)與應(yīng)用
      黑龍江電力(2017年1期)2017-05-17 04:25:16
      初識(shí)電腦端口
      電腦迷(2015年6期)2015-05-30 08:52:42
      生成樹協(xié)議實(shí)例探討
      關(guān)閉應(yīng)用程序更新提醒
      電腦迷(2012年15期)2012-04-29 17:09:47
      通過QQ郵件查看好友IP地址
      三星電子將開設(shè)應(yīng)用程序下載商店
      故城县| 绥化市| 遂昌县| 调兵山市| 资兴市| 扬州市| 红原县| 右玉县| 宜黄县| 罗江县| 昌黎县| 喀喇| 班戈县| 喀喇沁旗| 铁岭县| 凤阳县| 广丰县| 澄迈县| 芮城县| 深水埗区| 墨江| 疏勒县| 福海县| 遵义县| 井陉县| 射阳县| 旬邑县| 九寨沟县| 汶川县| 江山市| 龙江县| 兰溪市| 河西区| 五家渠市| 观塘区| 休宁县| 乌鲁木齐市| 武威市| 崇仁县| 湛江市| 缙云县|