A. 什麼是winsocket編程介面
Windows下網路編程的規范-Windows
Sockets是Windows下得到廣泛應用的、開放的、支持多種協議的網路編程介面。從1991年的1.0版到1995年的2.0.8版,經過不斷完善並在Intel、Microsoft、Sun、SGI、Informix、Novell等公司的全力支持下,已成為Windows網路編程的事實上的標准。
Windows
Sockets規范以U.C.
Berkeley大學BSD
UNIX中流行的Socket介面為範例定義了一套Micosoft
Windows下網路編程介面。它不僅包含了人們所熟悉的Berkeley
Socket風格的庫函數;也包含了一組針對Windows的擴展庫函數,以使程序員能充分地利用Windows消息驅動機制進行編程。Windows
Sockets規範本意在於提供給應用程序開發者一套簡單的API,並讓各家網路軟體供應商共同遵守。此外,在一個特定版本Windows的基礎上,Windows
Sockets也定義了一個二進制介面(ABI),以此來保證應用Windows
Sockets
API的應用程序能夠在任何網路軟體供應商的符合Windows
Sockets協議的實現上工作。因此這份規范定義了應用程序開發者能夠使用,並且網路軟體供應商能夠實現的一套庫函數調用和相關語義。遵守這套Windows
Sockets規范的網路軟體,我們稱之為Windows
Sockets兼容的,而Windows
Sockets兼容實現的提供者,我們稱之為Windows
Sockets提供者。一個網路軟體供應商必須百分之百地實現Windows
Sockets規范才能做到現Windows
Sockets兼容。任何能夠與Windows
Sockets兼容實現協同工作的應用程序就被認為是具有Windows
Sockets介面。我們稱這種應用程序為Windows
Sockets應用程序。Windows
Sockets規范定義並記錄了如何使用API與Internet協議族(IPS,通常我們指的是TCP/IP)連接,尤其要指出的是所有的Windows
Sockets實現都支持流套介面和數據報套介面.應用程序調用Windows
Sockets的API實現相互之間的通訊。Windows
Sockets又利用下層的網路通訊協議功能和操作系統調用實現實際的通訊工作。它們之間的關系如圖
通信的基礎是套介面(Socket),一個套介面是通訊的一端。在這一端上你可以找到與其對應的一個名字。一個正在被使用的套介面都有它的類型和與其相關的進程。套介面存在於通訊域中。通訊域是為了處理一般的線程通過套介面通訊而引進的一種抽象概念。套介面通常和同一個域中的套介面交換數據(數據交換也可能穿越域的界限,但這時一定要執行某種解釋程序)。Windows
Sockets規范支持單一的通訊域,即Internet域。各種進程使用這個域互相之間用Internet協議族來進行通訊(Windows
Sockets
1.1以上的版本支持其他的域,例如Windows
Sockets
2)。套介面可以根據通訊性質分類;這種性質對於用戶是可見的。應用程序一般僅在同一類的套介面間通訊。不過只要底層的通訊協議允許,不同類型的套介面間也照樣可以通訊。用戶目前可以使用兩種套介面,即流套介面和數據報套介面。流套介面提供了雙向的,有序的,無重復並且無記錄邊界的數據流服務。數據報套介面支持雙向的數據流,但並不保證是可靠,有序,無重復的。也就是說,一個從數據報套介面接收信息的進程有可能發現信息重復了,或者和發出時的順序不同。數據報套介面的一個重要特點是它保留了記錄邊界。對於這一特點,數據報套介面採用了與現在許多包交換網路(例如乙太網)非常類似的模型。
一個在建立分布式應用時最常用的範例便是客戶機/伺服器模型。在這種方案中客戶應用程序向伺服器程序請求服務。這種方式隱含了在建立客戶機/伺服器間通訊時的非對稱性。客戶機/伺服器模型工作時要求有一套為客戶機和伺服器所共識的慣例來保證服務能夠被提供(或被接受)。這一套慣例包含了一套協議。它必須在通訊的兩頭都被實現。根據不同的實際情況,協議可能是對稱的或是非對稱的。在對稱的協議中,每一方都有可能扮演主從角色;在非對稱協議中,一方被不可改變地
B. 如何利用Socket進行網路編程
Socket介面是TCP/IP網路的API,Socket介面定義了許多函數或常式,程序員可以用它們來開發TCP/IP網路上的應用程序。請參閱以下資料:socket非常類似於電話插座。以一個國家級電話網為例。電話的通話雙方相當於相互通信的 個進程,區號是它的網路地址;區內一個單位的交換機相當於一台主機,主機分配給每個用戶的局內號碼相當於socket號。任何用戶在通話之前,首先要佔有一部電話機,相當於申請一個socket;同時要知道對方的號碼,相當於對方有一個固定的socket。然後向對方撥號呼叫,相當於發出連接請求(假如對方不在同一區內,還要撥對方區號,相當於給出網路地址)。對方假如在場並空閑(相當於通信的另一主機開機且可以接受連接請求),拿起電話話筒,雙方就可以正式通話,相當於連接成功。雙方通話的過程,是一方向電話機發出信號和對方從電話機接收信號的過程,相當於向socket發送數據和從socket接收數據。通話結束後,一方掛起電話機相當於關閉socket,撤消連接。在電話系統中,一般用戶只能感受到本地電話機和對方電話號碼的存在,建立通話的過程,話音傳輸的過程以及整個電話系統的技術細節對他都是透明的,這也與socket機制非常相似。socket利用網間網通信設施實現進程通信,但它對通信設施的細節毫不關心,只要通信設施能提供足夠的通信能力,它就滿足了。至此,我們對socket進行了直觀的描述。抽象出來,socket實質上提供了進程通信的端點。進程通信之前,雙方首先必須各自創建一個端點,否則是沒有法建立聯系並相互通信的。正如打電話之前,雙方必須各自擁有一台電話機一樣。在網間網內部,每一個socket用一個半相關描述:(協議,本地地址,本地埠)一個完整的socket有一個本地唯一的socket號,由操作系統分配。最重要的是,socket是面向客戶/伺服器模型而設計的,針對客戶和伺服器程序提供不同的socket系統調用。客戶隨機申請一個socket(相當於一個想打電話的人可以在任何一台入網電話上撥號呼叫),系統為之分配一個socket號;伺服器擁有全局公認的socket,任何客戶都可以向它發出連接請求和信息請求(相當於一個被呼叫的電話擁有一個呼叫方知道的電話號碼)。socket利用客戶/伺服器模式巧妙地解決了進程之間建立通信連接的問題。伺服器socket半相關為全局所公認非常重要。讀者不妨考慮一下,兩個完全隨機的用戶進程之間如何建立通信?假如通信雙方沒有任何一方的socket固定,就好比打電話的雙方彼此不知道對方的電話號碼,要通話是不可能的。實際應用中socket例子Socket介面是訪問Internet使用得最廣泛的方法。如果你有一台剛配好TCP/IP協議的主機,其IP地址是 . . . ,此時在另一台主機或同一台主機上執行ftp . . . ,顯然無法建立連接。因" . . . "這台主機沒有運行FTP服務軟體。同樣,在另一台或同一台主機上運行瀏覽軟體如Netscape,輸入"http:// . . . ",也無法建立連接。現在,如果在這台主機上運行一個FTP服務軟體(該軟體將打開一個Socket,並將其綁定到 埠),再在這台主機上運行一個Web服務軟體(該軟體將打開另一個Socket,並將其綁定到 埠)。這樣,在另一台主機或同一台主機上執行ftp . . . ,FTP客戶軟體將通過 埠來呼叫主機上由FTP服務軟體提供的Socket,與其建立連接並對話。而在netscape中輸入"http:// . . . "時,將通過 埠來呼叫主機上由Web服務軟體提供的Socket,與其建立連接並對話。在Internet上有很多這樣的主機,這些主機一般運行了多個服務軟體,同時提供幾種服務。每種服務都打開一個Socket,並綁定到一個埠上,不同的埠對應於不同的服務。Socket正如其英文原意那樣,象一個多孔插座。一台主機猶如布滿各種插座的房間,每個插座有一個編號,有的插座提供 伏交流電,有的提供 伏交流電,有的則提供有線電視節目。客戶軟體將插頭插到不同編號的插座,就可以得到不同的服務。一個Server-Client模型程序的開發原理:伺服器,使用ServerSocket監聽指定的埠,埠可以隨意指定(由於 以下的埠通常屬於保留埠,在一些操作系統中不可以隨意使用,所以建議使用大於 的埠),等待客戶連接請求,客戶連接後,會話產生;在完成會話後,關閉連接。客戶端,使用Socket對網路上某一個伺服器的某一個埠發出連接請求,一旦連接成功,打開會話;會話完成後,關閉Socket。客戶端不需要指定打開的埠,通常臨時的、動態的分配一個 以上的埠。Socket介面是TCP/IP網路的API,Socket介面定義了許多函數或常式,程序員可以用它們來開發TCP/IP網路上的應用程序。要學Internet上的TCP/IP網路編程,必須理解Socket介面。Socket介面設計者最先是將介面放在Unix操作系統裡面的。如果了解Unix系統的輸入和輸出的話,就很容易了解Socket了。網路的Socket數據傳輸是一種特殊的I/O,Socket也是一種文件描述符。Socket也具有一個類似於打開文件的函數調用Socket(),該函數返回一個整型的Socket描述符,隨後的連接建立、數據傳輸等操作都是通過該Socket實現的。常用的Socket類型有兩種:流式Socket(SOCK_STREAM)和數據報式Socket(SOCK_DGRAM)。流式是一種面向連接的Socket,針對於面向連接的TCP服務應用;數據報式Socket是一種無連接的Socket,對應於無連接的UDP服務應用。Socket建立為了建立Socket,程序可以調用Socket函數,該函數返回一個類似於文件描述符的句柄。socket函數原型為:intsocket(intdomain,inttype,intprotocol);domain指明所使用的協議族,通常為PF_INET,表示互聯網協議族(TCP/IP協議族);type參數指定socket的類型:SOCK_STREAM或SOCK_DGRAM,Socket介面還定義了原始Socket(SOCK_RAW),允許程序使用低層協議;protocol通常賦值" "。Socket()調用返回一個整型socket描述符,你可以在後面的調用使用它。Socket描述符是一個指向內部數據結構的指針,它指向描述符表入口。調用Socket函數時,socket執行體將建立一個Socket,實際上"建立一個Socket"意味著為一個Socket數據結構分配存儲空間。Socket執行體為你管理描述符表。兩個網路程序之間的一個網路連接包括五種信息:通信協議、本地協議地址、本地主機埠、遠端主機地址和遠端協議埠。Socket數據結構中包含這五種信息。socket在測量軟體中的使用也很廣泛socket深層次理解Socket編程基本就是listen,accept以及send,write等幾個基本的操作。對於網路編程,我們也言必稱TCP/IP,似乎其它網路協議已經不存在了。對於TCP/IP,我們還知道TCP和UDP,前者可以保證數據的正確和可靠性,後者則允許數據丟失。最後,我們還知道,在建立連接前,必須知道對方的IP地址和埠號。除此,普通的程序員就不會知道太多了,很多時候這些知識已經夠用了。最多,寫服務程序的時候,會使用多線程來處理並發訪問。我們還知道如下幾個事實: 。一個指定的埠號不能被多個程序共用。比如,如果IIS佔用了 埠,那麼Apache就不能也用 埠了。 。很多防火牆只允許特定目標埠的數據包通過。 。服務程序在listen某個埠並accept某個連接請求後,會生成一個新的socket來對該請求進行處理。於是,一個困惑了我很久的問題就產生了。如果一個socket創建後並與 埠綁定後,是否就意味著該socket佔用了 埠呢?如果是這樣的,那麼當其accept一個請求後,生成的新的socket到底使用的是什麼埠呢(我一直以為系統會默認給其分配一個空閑的埠號)?如果是一個空閑的埠,那一定不是 埠了,於是以後的TCP數據包的目標埠就不是 了--防火牆一定會組織其通過的!實際上,我們可以看到,防火牆並沒有阻止這樣的連接,而且這是最常見的連接請求和處理方式。我的不解就是,為什麼防火牆沒有阻止這樣的連接?它是如何判定那條連接是因為connet 埠而生成的?是不是TCP數據包里有什麼特別的標志?或者防火牆記住了什麼東西?後來,我又仔細研讀了TCP/IP的協議棧的原理,對很多概念有了更深刻的認識。比如,在TCP和UDP同屬於傳輸層,共同架設在IP層(網路層)之上。而IP層主要負責的是在節點之間(EndtoEnd)的數據包傳送,這里的節點是一台網路設備,比如計算機。因為IP層只負責把數據送到節點,而不能區分上面的不同應用,所以TCP和UDP協議在其基礎上加入了埠的信息,埠於是標識的是一個節點上的一個應用。除了增加埠信息,UPD協議基本就沒有對IP層的數據進行任何的處理了。而TCP協議還加入了更加復雜的傳輸控制,比如滑動的數據發送窗口(SliceWindow),以及接收確認和重發機制,以達到數據的可靠傳送。不管應用層看到的是怎樣一個穩定的TCP數據流,下面傳送的都是一個個的IP數據包,需要由TCP協議來進行數據重組。所以,我有理由懷疑,防火牆並沒有足夠的信息判斷TCP數據包的信息,除了IP地址和埠號。而且,我們也看到,所謂的埠,是為了區分不同的應用的,以在不同的IP包來到的時候能夠正確轉發。TCP/IP只是一個協議棧,就像操作系統的運行機制一樣,必須要具體實現,同時還要提供對外的操作介面。就像操作系統會提供標準的編程介面,比如Win 編程介面一樣,TCP/IP也必須對外提供編程介面,這就是Socket編程介面--原來是這么回事啊!在Socket編程介面里,設計者提出了一個很重要的概念,那就是socket。這個socket跟文件句柄很相似,實際上在BSD系統里就是跟文件句柄一樣存放在一樣的進程句柄表裡。這個socket其實是一個序號,表示其在句柄表中的位置。這一點,我們已經見過很多了,比如文件句柄,窗口句柄等等。這些句柄,其實是代表了系統中的某些特定的對象,用於在各種函數中作為參數傳入,以對特定的對象進行操作--這其實是C語言的問題,在C++語言里,這個句柄其實就是this指針,實際就是對象指針啦。現在我們知道,socket跟TCP/IP並沒有必然的聯系。Socket編程介面在設計的時候,就希望也能適應其他的網路協議。所以,socket的出現只是可以更方便的使用TCP/IP協議棧而已,其對TCP/IP進行了抽象,形成了幾個最基本的函數介面。比如create,listen,accept,connect,read和write等等。現在我們明白,如果一個程序創建了一個socket,並讓其監聽 埠,其實是向TCP/IP協議棧聲明了其對 埠的佔有。以後,所有目標是 埠的TCP數據包都會轉發給該程序(這里的程序,因為使用的是Socket編程介面,所以首先由Socket層來處理)。所謂accept函數,其實抽象的是TCP的連接建立過程。accept函數返回的新socket其實指代的是本次創建的連接,而一個連接是包括兩部分信息的,一個是源IP和源埠,另一個是宿IP和宿埠。所以,accept可以產生多個不同的socket,而這些socket里包含的宿IP和宿埠是不變的,變化的只是源IP和源埠。這樣的話,這些socket宿埠就可以都是 ,而Socket層還是能根據源/宿對來准確地分辨出IP包和socket的歸屬關系,從而完成對TCP/IP協議的操作封裝!而同時,放火牆的對IP包的處理規則也是清晰明了,不存在前面設想的種種復雜的情形。
C. socket介面網路編程
面向無連接的端對端通信
//#include <winsock2.h>
//#pragma comment(lib,"WS2_32.lib")
WSADATA wsd;
SOCKET s;
char buf[1024];
if(WSAStartup(MAKEWORD(2,2),&wsd)!=0)
{
return -1;//失敗
}
s=socket(AF_INET,SOCK_DGRAM,0);
if(s==INVALID_SOCKET)
{
WSACleanup();
return -1;//創建套接字失敗
}
SOCKADDR_IN servAddr;
servAddr.sin_family=AF_INET;
servAddr.sin_addr.s_addr=inet_addr(%%1);
servAddr.sin_port=htons(INADDR_ANY);
if(bind(s,(SOCKADDR*)&servAddr,sizeof(SOCKADDR_IN))==SOCKET_ERROR)
{
closesocket(s);
WSACleanup();
return -1;//綁定套接字失敗
}
int nServAddrlen=sizeof(servAddr);
ZeroMemory(buf,sizeof(buf));
if(recvfrom(s,buf,size(buf),0,(SOCKADDR*)&servAddr,nServAddrlen)==SOCKET_ERROR)
{
closesocket(s);
WSACleanup();
return -1;//接收數據失敗
}
CString %%2(buf);
ZeroMemory(buf,sizeof(buf));
strcpy(buf,%%3);
SOCKADDR_IN clientAddr;
clientAddr.sin_family=AF_INET;
clientAddr.sin_addr.s_addr=inet_addr(%%4);
clientAddr.sin_port=htons((short)%%5);
int nClientlen=size(clientAddr);
if(sendto(s,buf,sizeof(buf),0,(SOCKADDR*)&clientAddr,nClientlen)==SOCKET_ERROR)
{
closesocket(s);
WSACleanup();
return -1;//向伺服器發送數據失敗
}
closesocket(s);
WSACleanup();
D. socket中有哪幾種連接方式區別是什麼
一、埠簡介 隨著計算機網路技術的發展,原來物理上的介面(如鍵盤、滑鼠、網卡、顯示卡等輸入/輸出介面)已不能滿足網路通信的要求,TCP/IP協議作為網路通信的標准協議就解決了這個通信難題。TCP/IP協議集成到操作系統的內核中,這就相當於在操作系統中引入了一種新的輸入/輸出介面技術,因為在TCP/IP協議中引入了一種稱之為Socket(套接字)應用程序介面。有了這樣一種介面技術,一台計算機就可以通過軟體的方式與任何一台具有Socket介面的計算機進行通信。埠在計算機編程上也就是Socket介面。 有了這些埠後,這些埠又是如何工作呢?例如一台伺服器為什麼可以同時是Web伺服器,也可以是FTP伺服器,還可以是郵件伺服器等等呢?其中一個很重要的原因是各種服務採用不同的埠分別提供不同的服務,比如:通常TCP/IP協議規定Web採用80號埠,FTP採用21號埠等,而郵件伺服器是採用25號埠。這樣,通過不同埠,計算機就可以與外界進行互不幹擾的通信。 據專家們分析,伺服器埠數最大可以有65535個,但是實際上常用的埠才幾十個,由此可以看出未定義的埠相當多。這是那麼多黑客程序都可以採用某種方法,定義出一個特殊的埠來達到入侵的目的的原因所在。為了定義出這個埠,就要依靠某種程序在計算機啟動之前自動載入到內存,強行控制計算機打開那個特殊的埠。這個程序就是後門程序,這些後門程序就是常說的木馬程序。簡單的說,這些木馬程序在入侵前是先通過某種手段在一台個人計算機中植入一個程序,打開某個(些)特定的埠,俗稱後門(BackDoor),使這台計算機變成一台開放性極高(用戶擁有極高許可權)的FTP伺服器,然後從後門就可以達到侵入的目的。 二、埠的分類 埠的分類根據其參考對象不同有不同劃分方法,如果從埠的性質來分,通常可以分為以下三類: (1)公認埠(Well Known Ports):這類埠也常稱之為常用埠。這類埠的埠號從0到1024,它們緊密綁定於一些特定的服務。通常這些埠的通信明確表明了某種服務的協議,這種埠是不可再重新定義它的作用對象。例如:80埠實際上總是HTTP通信所使用的,而23號埠則是Telnet服務專用的。這些埠通常不會像木馬這樣的黑客程序利用。為了使大家對這些常用埠多一些認識,在本章後面將詳細把這些埠所對嬗Φ姆?窠?辛斜恚?└魑煥斫夂筒慰肌? (2) 注冊埠(Registered Ports):埠號從1025到49151。它們鬆散地綁定於一些服務。也是說有許多服務綁定於這些埠,這些埠同樣用於許多其他目的。這些埠多數沒有明確的定義服務對象,不同程序可根據實際需要自己定義,如後面要介紹的遠程式控制制軟體和木馬程序中都會有這些埠的定義的。記住這些常見的程序埠在木馬程序的防護和查殺上是非常有必要的。常見木馬所使用的埠在後面將有詳細的列表。 (3) 動態和/或私有埠(Dynamic and/or Private Ports):埠號從49152到65535。理論上,不應把常用服務分配在這些埠上。實際上,有些較為特殊的程序,特別是一些木馬程序就非常喜歡用這些埠,因為這些埠常常不被引起注意,容易隱蔽。 如果根據所提供的服務方式的不同,埠又可分為TCP協議埠和UDP協議埠兩種。因為計算機之間相互通信一般採用這兩種通信協議。前面所介紹的連接方式是一種直接與接收方進行的連接,發送信息以後,可以確認信息是否到達,這種方式大多採用TCP協議;另一種是不是直接與接收方進行連接,只管把信息放在網上發出去,而不管信息是否到達,也就是前面所介紹的無連接方式。這種方式大多採用UDP協議,IP協議也是一種無連接方式。對應使用以上這兩種通信協議的服務所提供的埠,也就分為TCP協議埠和UDP協議埠。 使用TCP協議的常見埠主要有以下幾種: (1) FTP:定義了文件傳輸協議,使用21埠。常說某某計算機開了FTP服務便是啟動了文件傳輸服務。下載文件,上傳主頁,都要用到FTP服務。 (2)Telnet:它是一種用於遠程登陸的埠,用戶可以以自己的身份遠程連接到計算機上,通過這種埠可以提供一種基於DOS模式下的通信服務。如以前的BBS是純字元界面的,支持BBS的伺服器將23埠打開,對外提供服務。 (3)SMTP:定義了簡單郵件傳送協議,現在很多郵件伺服器都用的是這個協議,用於發送郵件。如常見的免費郵件服務中用的就是這個郵件服務埠,所以在電子郵件設置中常看到有這么SMTP埠設置這個欄,伺服器開放的是25號埠
E. socket編程到底是什麼
socket 其實就是操作系統提供給程序員操作「網路協議棧」的介面,說人話就是,你能通過socket 的介面,來控制協議找工作,從而實現網路通信,達到跨主機通信。
協議棧的上半部分有兩塊,分別是負責收發數據的 TCP 和 UDP 協議,它們兩會接受應用層的委託執行收發數據的操作。
協議棧的下面一半是用 IP 協議控制網路包收發操作,在互聯網上傳數據時,數據會被切分成一塊塊的網路包,而將網路包發送給對方的操作就是由 IP 負責的。這里需要注意的是,服務端調用 accept 時,連接成功了會返回一個已完成連接的 socket,後續用來傳輸數據。
所以,監聽的 socket 和真正用來傳送數據的 socket,是「兩個」 socket,一個叫作監聽 socket,一個叫作已完成連接 socket。成功連接建立之後,雙方開始通過 read 和 write 函數來讀寫數據,就像往一個文件流裡面寫東西一樣。
F. 在windows下用C語言如何實現socket網路編程,需要用到哪些頭文件或者庫
需要用到的頭文件包含:
#include <winsock2.h>
#include <windows.h>
與Linux環境下socket編程相比,windows環境多了一個步驟:啟動或者初始化winsock庫
Winsock,一種標准API,一種網路編程介面,用於兩個或多個應用程序(或進程)之間通過網路進行數據通信。具有兩個版本:
Winsock 1:
Windows CE平台支持。
頭文件:WinSock.h
庫:wsock32.lib
Winsock 2:
部分平台如Windows CE貌似不支持。通過前綴WSA可以區別於Winsock 1版本。個別函數如WSAStartup、WSACleanup、WSARecvEx、WSAGetLastError都屬於Winsock 1.1規范的函數;
頭文件:WinSock2.h
庫:ws2_32.lib
mswsock.h用於編程擴展,使用時必須鏈接mswsock.dll
(6)socket編程介面擴展閱讀
winsock庫的載入與卸載:
載入:int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);
載入成功,返回值為0。
WORD wVersionRequested:載入的winsock版本,使用宏MAKEWORD(x, y),x表示高位元組,y表示低位元組。然而使用時MAKEWORD(2, 2)。高位元組與低位元組相同~~
LPWSADATA lpWSAData:WSADATA結構的指針,傳入參數後,系統幫助我們填充版本信息。有興趣的可以看看結構體內容,不過基本用不著。
卸載:int WSACleanup(void);比起載入,卸載的函數真是輕松愉快。