程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 學用VC++進行Winsock編程--Client端

學用VC++進行Winsock編程--Client端

編輯:關於C語言
 

說到Winsock,可能很多人還不太了解,但說到OICQ、ICQ、Foxmail、Netants、CuteFTP以及大名鼎鼎的BO2K等等,大家都應該是很熟悉的。如今是網絡時代,這些基於網絡的軟件真的是紅紅火火!那你有沒有想過這些軟件是怎麼寫出來的呢?這就是本文將要介紹的內容:Socket編程!

Socket(中文譯名:套接字)最初在Unix上出現,並很快成為Unix上最流行的網絡編程接口之一。後來,微軟將它引入到Windows中並得到實現,於是從Windows 95、WinNT4開始,系統就內置了Winsock1.1,後來到了Windows98、Windows2000,它內置的Winsock DLL更新為Winsock2.2。Winsock1.1有2種I/O方式,2種I/O模型,到了Winsock2.2,則有了2種I/O方式,5種I/O模型。另外,Winsock2.2對Socket進行了很多擴充與改進,包括名字解析、異步處理等。這些都是很有用的內容,但也比較復雜,要想在短短一篇文章裡講清楚是不可能的,本文的目的只是為你開個頭,俗話說:萬事開頭難!其實Winsock編程是很例行公式化的。不過值得注意的是:有時它也很難把握,因為它編程的對象是網絡,有時你發現運行程序得不到預期的結果,但卻很難調試出到底哪裡出了問題!

下面將向你介紹基本的Socket的客戶端函數,並給出了一個簡單的多線程端口掃描器的源代碼!

先講一下基本的編程步驟:

1.由於Winsock目前有兩個版本:2.2和1.1,所以我們首先必須判斷系統所支持的Winsock版本!這就要靠WSAStartup函數了!另外還有一個WSACleanup函數!這兩個函數是Winsock編程必須調用的,其中WSAStartup函數的功能是初始化Winsock DLL,因為在Windows下,Socket是以DLL的形式實現的。1.1版本的DLL為Winsock.dll,而2.2版本的DLL則為Wsock32.dll,其中在2.2版本的系統中,對Winsock1.1函數的調用會由Wsock32.dll自動映射到Winsock.dll。WSAStartup函數的功能就是初始化DLL,其函數原型為:

int WSAStartup (WORD wVersionRequested,LPWSADATA lpWSAData);

其中第一個參數為你所想需要的Winsock版本!低字節為主版本,高字節為副版本!由於目前Winsock有兩個版本:1.1和2.2,因此該參數可以是0x101或0x202;第二個參數是一個WSADATA結構,用於接收函數的返回信息!WSAStartup函數調用成功會返回0,否則返回非0值!

示例代碼:

WSADATA wsaData;

if(WSAStartup(0x101,&wsaData))

{

//錯誤處理!

}

這裡有一點題外話,由於Win 95,Win NT4自帶的Winsock是1.1版本的,所以如果你的程序是基於Winsock2.2的,那很可能無法在上面運行!因此,如果你希望你寫的程序被所有Windows平台支持的話,最好將其聲明成1.1版的,不過這樣將無法使用很多Winsock2.2才有的特性!至於WSACleanup的用法很簡單,用“WSACleanup();”就行了!另外,在DLL內部維持著一個計數器,只有第一次調用WSAStartup才真正裝載DLL,以後的調用只是簡單的增加計數器,而WSACleanup函數的功能則剛好相反,每調用一次使計數器減1,當計數器減到0時,DLL就從內存中被卸載!因此,你調用了多少次WSAStartup,就應相應的調用多少次的WSACleanup。

2.創建套接字

創建套接字有兩個函數,socket和WSASocket,前者是標准的Socket函數,而後者是微軟對Socket的擴展函數。socket函數有3個參數,第一個是指定通信發生的區域,在UNIX下有AF_UNIX、AF_INET、AF_NS等,而在Winsock1.1下只支持AF_INET,到了2.2則添了AF_IRDA(紅外線通信)、AF_ATM(異步網絡通信)、AF_NS、AF_IPX等;第2個參數是套接字的類型,在AF_INET地址族下,有SOCK_STREAM、SOCK_DGRAM、SOCK_RAW三種套接字類型。SOCK_STREAM也就是通常所說的TCP,而SOCK_DGRAM則是通常所說的UDP,而SOCK_RAW則是用於提供一些較低級的控制的;第3個參數依賴於第2個參數,用於指定套接字所用的特定協議,設為0表示使用默認的協議。socket函數調用成功返回一個套接字描述符,錯誤則返回SOCKET_ERROR。

示例代碼:

SOCKET sk;

sk=socket(AF_INET,SOCK_STREAM,0);

if(sk==SOCKET_ERROR)

{

//錯誤處理

}

3.連接服務器

在成功調用了socket函數後,對客戶端來說就是與服務器端建立連接。同樣,建立連接需要兩個函數:connect和WSAConnect。前者是標准的Socket函數,後者是微軟的擴展函數。connect函數有3個參數,第1個是連接所使用的套接字描述符,第2個參數是一個sockaddr結構,sockaddr結構是一個通用的結構,它只是簡單地定義了一個字節數組,在TCP/IP下一般將其解釋為sockaddr_in結構,第3個參數則是該結構的長度,一般用sizeof函數來取得。connect函數調用失敗則返回SOCKET_ERROR!

示例代碼:

sockaddr_in sock;

sock.sin_family=AF_INET;

sock.sin_port=htons(80);

sock.sin_addr.s_addr=inet_addr(“202.205.210.1”);  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved