• 
    

    
    

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

      ?

      在VC環(huán)境下利用WinSock實現(xiàn)網(wǎng)絡(luò)通信

      2012-04-29 00:44:03高靈霞
      電腦知識與技術(shù) 2012年20期

      高靈霞

      摘要:闡述了Winsock的相關(guān)概念,介紹了套接字的相關(guān)技術(shù)和套接字編程原理,分析實現(xiàn)網(wǎng)絡(luò)通信的面向連接的套接字編程模型和面向無連接的套接字編程模型,給出了在VC環(huán)境下利用Winsock開發(fā)網(wǎng)絡(luò)應(yīng)用程序的具體方法和程序代碼,來實現(xiàn)面向連接的網(wǎng)絡(luò)通信。

      關(guān)鍵詞:TCP/IP協(xié)議;套接字;網(wǎng)絡(luò)編程;Winsock

      中圖分類號:TP393文獻標識碼:A文章編號:1009-3044(2012)20-4819-04

      On the Realization of Network Communication by Implementing WinSock in VC

      GAO Ling-xia

      (Chongqing College of Electronic Engineering, Department of Computer Science, Chongqing 401331,China)

      Abstract: This paper describes the related concepts of Winsock, introduces the related technology of socket and programming principle of socket, analysis of network communication of connection-oriented socket programming model and connectionless socket programming model. In VC environment, development of network application methods and program code , Using Winsock to realize connection of ori ented network communication.

      Key words: TCP/IP protocol; socket ; network programming; winsock

      為了實現(xiàn)C/S模型的網(wǎng)絡(luò)編程,90年代初,由Microsoft聯(lián)合了其他幾家公司共同制定了一套WINDOWS下的網(wǎng)絡(luò)編程接口[1],即Windows Sockets規(guī)范,它不是一種網(wǎng)絡(luò)協(xié)議,而是一套開放的、支持多種協(xié)議的Windows下的網(wǎng)絡(luò)編程接口。Socket(套接字)實際在計算機中提供了一個通信端口,可以通過這個端口與任何一個具有Socket接口的計算機通信。應(yīng)用程序在網(wǎng)絡(luò)上傳輸,接收的信息都通過這個Socket接口來實現(xiàn)?,F(xiàn)在Socket接口幾乎是TCP/IP網(wǎng)絡(luò)標準API,很多TCP/IP的網(wǎng)絡(luò)應(yīng)用程序都是基于Socket而編寫的。

      雖然現(xiàn)在有很多工具如Web瀏覽器、FTP程序可以在網(wǎng)絡(luò)上傳輸數(shù)據(jù)和文件,但是通過WinSock編程有更大的靈活性,并且不需關(guān)心網(wǎng)絡(luò)連接細節(jié)。

      1 Client/Server (客戶機/服務(wù)器)模型

      在網(wǎng)絡(luò)編程中最常用的方案便是Client/Server (客戶機/服務(wù)器)模型[2]。在這種方案中客戶應(yīng)用程序向服務(wù)器程序請求服務(wù)。一個服務(wù)程序通常在一個眾所周知的地址監(jiān)聽對服務(wù)的請求,也就是說,服務(wù)進程一直處于休眠狀態(tài),直到一個客戶向這個服務(wù)的地址提出了連接請求。在這個時刻,服務(wù)程序被"驚醒"并且為客戶提供服務(wù)-對客戶的請求作出適當?shù)姆磻?yīng)。通信過程如圖1所示。

      2套接字

      套接字是網(wǎng)絡(luò)計算機與應(yīng)用程序之間發(fā)送和接收數(shù)據(jù)方式的一種抽象描述[1]。用來實現(xiàn)主機和主機通信的一個接口,完成主機間的通信操作。它位于協(xié)議之上,屏蔽了底層的協(xié)議,能夠?qū)崿F(xiàn)各種類型的通信操作。它是網(wǎng)絡(luò)通信中應(yīng)用程序?qū)?yīng)的進程和網(wǎng)絡(luò)協(xié)議之間的接口。網(wǎng)絡(luò)應(yīng)用程序調(diào)用Winsock API函數(shù)實現(xiàn)相互之間的通信,同時,Winsock利用下層的網(wǎng)絡(luò)通信協(xié)議和操作系統(tǒng)實現(xiàn)實際的通信,如圖2所示。

      圖2應(yīng)用進程使用Winsock進行通信

      在網(wǎng)絡(luò)中進行通信,至少需要一對套接字,其中一個運行于客戶機端,稱之為ClientSocket[3];另一個運行于服務(wù)器端,稱之為Ser verSocket。套接字主要有三個參數(shù),分別為通信的目的IP地址,使用的傳輸層協(xié)議(TCP或UDP)和使用的端口。根據(jù)這些參數(shù),應(yīng)用層就可以和傳輸層通過socket接口,實現(xiàn)數(shù)據(jù)傳輸。

      2.1 Windows Sockets的相關(guān)技術(shù)分析

      2.1.1 Windows Sockets的版本

      常用的Windows Sockets有兩個版本:WinSock 1.1網(wǎng)絡(luò)編程接口和WinSock2.2網(wǎng)絡(luò)編程接口。WinSock1.1由動態(tài)鏈接庫WIN SOCK.DLL支持,主要應(yīng)用在Windows95中,WinSock2.2由動態(tài)鏈接庫WINSOCK32.DLL支持,主要應(yīng)用在Windows98和Win dows2000中。WinSock2.2與低版本W(wǎng)inSock1.1相比,主要對一些協(xié)議進行了擴充,如IPX、NETBIOS等,同時對WinSock1.1的函數(shù)完成兼容。

      2.1.2阻塞與非阻塞

      套接字具備兩種模式[4]:阻塞和非阻塞模式。當套接字處于阻塞模式時調(diào)用高模式的函數(shù)時,需要消耗一定的時間來等待操作的完成,而當套接字處于非阻塞模式時,調(diào)用函數(shù)立即返回,但通常會出錯。當一特定的WinSock API函數(shù)指出一個錯誤發(fā)生時,需要獲取對應(yīng)的錯誤代碼,根據(jù)WinSock版本的不同,包含在不同的頭文件中。

      2.1.3網(wǎng)絡(luò)字節(jié)順序

      網(wǎng)絡(luò)字節(jié)就是網(wǎng)絡(luò)上描述整數(shù)或浮點數(shù)的字節(jié)發(fā)送順序(哪個字節(jié)被先發(fā)出去,哪個字節(jié)后發(fā)出去)。網(wǎng)絡(luò)字節(jié)通常先傳遞高字節(jié),而再傳遞低字節(jié)。而主機字節(jié)就是計算機內(nèi)存中存放的整數(shù)或浮點數(shù)的方式,字節(jié)在內(nèi)存中低字節(jié)在前,高字節(jié)在后。為了數(shù)據(jù)的一致性,就要把本地的數(shù)據(jù)轉(zhuǎn)換成網(wǎng)絡(luò)使用的格式,然后發(fā)送出去,接收的時候要轉(zhuǎn)換成主機方式才能使用。下面的API函數(shù)將從主機字節(jié)順序向網(wǎng)絡(luò)字節(jié)順序的轉(zhuǎn)換:

      1)htonl():參數(shù)是主機字節(jié)順序的一個4字節(jié)數(shù),函數(shù)返回網(wǎng)絡(luò)字節(jié)順序的數(shù)。

      2)WSAHtonl():參數(shù)是主機字節(jié)順序的一個4字節(jié)數(shù),函數(shù)返回網(wǎng)絡(luò)字節(jié)順序的數(shù)。3)htons():參數(shù)是主機字節(jié)順序的一個2字節(jié)數(shù),函數(shù)返回網(wǎng)絡(luò)字節(jié)順序的數(shù)。

      4)WSAHtons():參數(shù)是主機字節(jié)順序的一個2字節(jié)數(shù),函數(shù)返回網(wǎng)絡(luò)字節(jié)順序的數(shù)。

      2.2 WinSock技術(shù)特點

      2.2.1套接字的分類

      套接字根據(jù)通信的性質(zhì)可以分為三類,在設(shè)計網(wǎng)絡(luò)應(yīng)用程序時,根據(jù)不同的要求來選擇相應(yīng)的套接字,只有相同類型的套接字才能相互通信。

      流套接字(SOCK_STREAM)。提供一個面向連接可靠的數(shù)據(jù)傳輸服務(wù),數(shù)據(jù)無差錯、無重復(fù)地發(fā)送,且按發(fā)送順序接收。

      數(shù)據(jù)報式套接字(SOCK_DGRAM)。提供一個無連接服務(wù)。數(shù)據(jù)包以獨立包形式被發(fā)送,不提供無錯保證,數(shù)據(jù)可能丟失或重復(fù),并且接收順序混亂。

      原始式套接字(SOCK_RAW)。該接口允許對較低層協(xié)議,如IP、ICMP直接訪問。常用于檢驗新的協(xié)議實現(xiàn)或訪問現(xiàn)有服務(wù)中配置的新設(shè)備,一般不提供給普通用戶。

      2.2.2異步選擇機制

      Windows Sockets的異步選擇機制為套接字編程提供了一種網(wǎng)絡(luò)事件驅(qū)動的程序設(shè)計方法[4]。通過異步選擇函數(shù)WSAAsyncSe lect(),可以為應(yīng)用程序程序注冊一個或多個感興趣的網(wǎng)絡(luò)事件,如讀寫事件、連接事件、接受請求事件等。用來注冊異步消息的函數(shù)是WSAAsyncSelect函數(shù),它請求Windows Sockets DLL在檢測到套接字上發(fā)生的網(wǎng)絡(luò)事件時,向窗口發(fā)送一個消息。它自動地設(shè)置套接字處于非阻塞工作方式,事件可以是一個或多個組合而成。

      2.2.3對錯誤的處理

      錯誤的發(fā)現(xiàn)和處理對于應(yīng)用程序是非常重要的,對WinSock而言,經(jīng)常會返回一下錯誤信息,最常見的是SOCKET_ERROR,它是一個值為-1的常量,這時可以用WSAGetLastError函數(shù)來獲得一段代碼,該代碼可以清楚地表明錯誤產(chǎn)生的原因和類型,該函數(shù)的原型為:

      Int WSAGetLastError(void);

      2.3套接字編程模型

      2.3.1面向連接的套接字編程模型

      套接字編程分為面向連接的套接字和面向無連接套接字的兩種編程模型。在面向連接的套接字模型中,服務(wù)器需要等待客戶端向其提出的建立連接的申請,一旦接收到客戶端的連接請求,服務(wù)器返回一個新的套接字描述符,通過該描述符調(diào)用數(shù)據(jù)傳輸函數(shù)可以與客戶端進行數(shù)據(jù)的收發(fā)[5]。面向有連接的編程模型如圖3所示。

      圖3面向連接的套接字模型

      2.3.2面向無連接的套接字編程模型

      面向無連接的編程模型相對比較簡單。服務(wù)器和客戶端沒有明確的界限,而且是對等的關(guān)系??蛻舳酥g首先創(chuàng)建一個數(shù)據(jù)報式套接字,并將其綁定到地址和端口上??蛻舳伺c服務(wù)端的數(shù)據(jù)交換通過sendto和recvfrom函數(shù)完成,在調(diào)用這兩個函數(shù)時都指定對方的地址,而不用建立連接。最后,都需要調(diào)用closesocket關(guān)閉套接字。面向無連接的套接字編程模型如下圖4所示。

      3 WinSock實現(xiàn)基于TCP的客戶端/服務(wù)器通信

      此實例的目的是驗證面向連接的通信模型,通過C++編碼實現(xiàn)程序間的網(wǎng)絡(luò)通信。實例分成兩個程序,服務(wù)器端程序和客戶端程序。

      1)服務(wù)器程序主要代碼

      //定義兩個socket變量,一個用來監(jiān)聽,一個用來建立連接和提供服務(wù)

      SOCKET listenSocket,acceptSocket;

      //設(shè)置服務(wù)器、客戶的地址和端口

      struct sockaddr_in serv,cliet;

      listenSocket=socket(AF_INET,SOCK_STREAM,0);//創(chuàng)建監(jiān)聽流式socket

      if(listenSocket==INVALID_SOCKET)

      { printf("建立socket出錯 ");return 0;

      }

      //設(shè)置服務(wù)器地址信息

      serv.sin_family=AF_INET;

      serv.sin_port=htons(6666);

      //設(shè)置監(jiān)聽端口是6666

      serv.sin_addr.s_addr=htonl(INADDR_ANY);//將4字節(jié)主機字節(jié)順序轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)順序,INADDR_ANY為系統(tǒng)指定的IP地址。//將監(jiān)聽socket與服務(wù)器地址綁定

      if(bind(listenSocket,(LPSOCKADDR)&serv,sizeof(serv))==SOCKET_ERROR)

      {printf("綁定出錯 ");return 0;

      }

      if(listen(listenSocket,5)==SOCKET_ERROR)//開始監(jiān)聽

      {printf("監(jiān)聽出錯 ");return 0;

      }

      //等待客戶連接請求,有連接請求到來,則用acceptSocket與其建立連接,進行通信

      int len=sizeof(cliet);

      acceptSocket=accept(listenSocket,(struct sockaddr *)&cliet,&len); if(acceptSocket==INVALID_SOCKET)

      {printf("建立連接出錯 ");break;}

      char buf[1024];

      ret=recv(acceptSocket,buf,sizeof(buf),0);//接收數(shù)據(jù)

      if(ret==0) return 0; char str[1024]={0};

      printf("來自客戶端的信息:");

      printf(buf);printf(" ");

      memset(buf,0,sizeof(buf));

      strcpy(buf,"ok");

      ret=send(acceptSocket,buf,sizeof(buf),0);//發(fā)送數(shù)據(jù)

      if(ret==SOCKET_ERROR)

      {printf("發(fā)送數(shù)據(jù)出錯 ");return 0;}

      closesocket(acceptSocket);//關(guān)閉socket

      closesocket(listenSocket);

      2)客戶端主要代碼

      SOCKET clientSocket;//定義客戶端socket變量

      struct sockaddr_in serv; //定義服務(wù)器端地址信息

      char buf[1024];//設(shè)置服務(wù)器地址信息

      serv.sin_family=AF_INET;

      serv.sin_port=htons(8888);

      //設(shè)置需連接的服務(wù)器的監(jiān)聽端口(必須與服務(wù)器端綁定的監(jiān)聽端口一致)

      serv.sin_addr.s_addr=inet_addr("192.168.1.100");

      //此處應(yīng)設(shè)置為服務(wù)器端的IP地址

      clientSocket=socket(AF_INET,SOCK_STREAM,0);//建立客戶端socket if(clientSocket==INVALID_SOCKET)

      {printf("建立socket出錯!");return;

      }

      //請求與服務(wù)器建立TCP連接

      if(connect(clientSocket,(struct sockaddr *)&serv,sizeof(serv))==INVALID_SOCKET)

      {printf("請求建立連接出錯!");return;

      }

      //發(fā)送數(shù)據(jù)給服務(wù)器

      memset(buf,0,sizeof(buf));

      strcpy(buf,"hello,How are you!");

      ret=send(clientSocket,buf,sizeof(buf),0);

      if(ret==SOCKET_ERROR)

      {printf("發(fā)送數(shù)據(jù)出錯");return;

      }

      //接收服務(wù)器發(fā)回的數(shù)據(jù)

      memset(buf,0,sizeof(buf));

      ret=recv(clientSocket,buf,sizeof(buf),0);

      if(ret==0)return;

      printf("接收到服務(wù)器回復(fù)信息內(nèi)容:");

      printf(buf);printf(" ");

      closesocket(clientSocket);//關(guān)閉socket

      (3)該實例是面向連接的TCP協(xié)議,因此套接字采用流套接字(SOCK_STREAM),服務(wù)器在與客戶端建立連接成功后,接收客戶端發(fā)來信息“Hello,How are you!”,接收成功后,向客戶端發(fā)送“ok!”字符串。實現(xiàn)服務(wù)器與客戶端的網(wǎng)絡(luò)通信。

      4總結(jié)

      隨著Internet的發(fā)展,網(wǎng)絡(luò)應(yīng)用軟件的開發(fā)需求與日俱增。各式各樣的網(wǎng)絡(luò)應(yīng)用軟件也催生著各種網(wǎng)絡(luò)編程技術(shù)的進步。用套接字(Socket)來實現(xiàn)互聯(lián)網(wǎng)上的進程通訊,從而實現(xiàn)各種網(wǎng)絡(luò)應(yīng)用功能,是開發(fā)網(wǎng)絡(luò)應(yīng)用程序的重要方法。對于分布于不同主機上的進程通信,Sockets無疑是一種理想的手段,通過它可以方便地交換數(shù)據(jù)。Winsock技術(shù)的出現(xiàn)極好地屏蔽了網(wǎng)絡(luò)低層復(fù)雜的結(jié)構(gòu)和協(xié)議,這使得基于Winsock的網(wǎng)絡(luò)應(yīng)用程序可以在不同類型的網(wǎng)絡(luò)上運行。同時使Winsock成為網(wǎng)絡(luò)編程的最流行技術(shù),可以說,套接字是網(wǎng)絡(luò)通信的基石。

      參考文獻:

      [1]延霞,謝斐.Visual C++網(wǎng)絡(luò)編程技術(shù)[M].北京:中國水利水電出版社,2010:6-11.

      [2]鄭阿奇.Visual C++6.0應(yīng)用案例教程[M].北京:電子工業(yè)出版社,2010:160-170.

      [3]鄒月,陳建兵.Socket網(wǎng)絡(luò)編程與實現(xiàn)[J].電腦編程技巧與維護,2009,(8):10-12.

      [4]陳孚.VC環(huán)境下基于C/S模式的網(wǎng)絡(luò)考試系統(tǒng)研究與實現(xiàn)[J].電腦編程技巧與維護.2011,(12):59-60.

      [5]任志考,李朝玲. Visual C++6.0環(huán)境下Winsock的研究與應(yīng)用[J].信息技術(shù).2006,(8):96-99.

      略阳县| 将乐县| 宁都县| 富蕴县| 镇原县| 岚皋县| 博兴县| 商城县| 南木林县| 靖远县| 偃师市| 旌德县| 白沙| 新邵县| 琼海市| 乐清市| 辛集市| 河北省| 漳浦县| 县级市| 吉安市| 开远市| 兰考县| 汕尾市| 定陶县| 东兴市| 泾阳县| 惠安县| 凯里市| 秦安县| 文水县| 河源市| 全州县| 东山县| 太仓市| 萝北县| 调兵山市| 海晏县| 崇明县| 遵义市| 临泽县|