舉例說明
Socket又稱"套接字",應用程式通常通過"套接字"向網路發出請求或者應答網路請求。
以J2SDK-1.3為例,Socket和ServerSocket類庫位於java.net包中。ServerSocket用於伺服器端,Socket是建立網路連線時使用的。在連線成功時,應用程式兩端都會產生一個Socket實例,操作這個實例,完成所需的會話。對於一個網路連線來說,套接字是平等的,並沒有差別,不因為在伺服器端或在客戶端而產生不同級別。不管是Socket還是ServerSocket它們的工作都是通過SocketImpl類及其子類完成的。
現象解釋
Socket非常類似於電話插座。以一個國家級電話網為例,電話的通話雙方相當於相互通信的2個進程,區號是它的網路地址;區內一個單位的交換機相當於一台主機,主機分配給每個用戶的局內號碼相當於Socket號。任何用戶在通話之前,首先要占有一部電話機,相當於申請一個Socket;同時要知道對方的號碼,相當於對方有一個固定的Socket。然後向對方撥號呼叫,相當於發出連線請求(假如對方不在同一區內,還要撥對方區號,相當於給出網路地址)。假如對方在場並空閒(相當於通信的另一主機開機且可以接受連線請求),拿起電話話筒,雙方就可以正式通話,相當於連線成功。雙方通話的過程,是一方向電話機發出信號和對方從電話機接收信號的過程,相當於向Socket傳送數據和從socket接收數據。通話結束後,一方掛起電話機相當於關閉Socket,撤消連線。
在電話系統中,一般用戶只能感受到本地電話機和對方電話號碼的存在,建立通話的過程,話音傳輸的過程以及整個電話系統的技術細節對他都是透明的,這也與Socket機制非常相似。Socket利用網間網通信設施實現進程通信,但它對通信設施的細節毫不關心,只要通信設施能提供足夠的通信能力,它就滿足了。
至此,我們對Socket進行了直觀的描述。抽象出來,Socket實質上提供了進程通信的端點。進程通信之前,雙方首先必須各自創建一個端點,否則是沒有辦法建立聯繫並相互通信的。正如打電話之前,雙方必須各自擁有一台電話機一樣。
在網間網內部,每一個Socket用一個半相關描述:(協定,本地地址,本地連線埠)。
一個完整的Socket有一個本地唯一的Socket號,由作業系統分配。
最重要的是,Socket是面向客戶/伺服器模型而設計的,針對客戶和伺服器程式提供不同的Socket系統調用。客戶隨機申請一個Socket(相當於一個想打電話的人可以在任何一台入網電話上撥號呼叫),系統為之分配一個Socket號;伺服器擁有全局公認的Socket,任何客戶都可以向它發出連線請求和信息請求(相當於一個被呼叫的電話擁有一個呼叫方知道的電話號碼)。
Socket利用客戶/伺服器模式巧妙地解決了進程之間建立通信連線的問題。伺服器Socket半相關為全局所公認非常重要。讀者不妨考慮一下,兩個完全隨機的用戶進程之間如何建立通信?假如通信雙方沒有任何一方的Socket固定,就好比打電話的雙方彼此不知道對方的電話號碼,要通話是不可能的。
連線過程
根據連線啟動的方式以及本地套接字要連線的目標,套接字之間的連線過程可以分為三個步驟:伺服器監聽,客戶端請求,連線確認。
(1)伺服器監聽:是伺服器端套接字並不定位具體的客戶端套接字,而是處於等待連線的狀態,實時監控網路狀態。
(2)客戶端請求:是指由客戶端的套接字提出連線請求,要連線的目標是伺服器端的套接字。為此,客戶端的套接字必須首先描述它要連線的伺服器的套接字,指出伺服器端套接字的地址和連線埠號,然後就向伺服器端套接字提出連線請求。
(3)連線確認:是指當伺服器端套接字監聽到或者說接收到客戶端套接字的連線請求,它就回響客戶端套接字的請求,建立一個新的執行緒,把伺服器端套接字的描述發給客戶端,一旦客戶端確認了此描述,連線就建立好了。而伺服器端套接字繼續處於監聽狀態,繼續接收其他客戶端套接字的連線請求。
常用函式
創建
函式原型:
int socket(int domain, int type, int protocol);
參數說明:
domain:協定域,又稱協定族(family)。常用的協定族有AF_INET、AF_INET6、AF_LOCAL(或稱AF_UNIX,Unix域Socket)、AF_ROUTE等。協定族決定了socket的地址類型,在通信中必須採用對應的地址,如AF_INET決定了要用ipv4地址(32位的)與連線埠號(16位的)的組合、AF_UNIX決定了要用一個絕對路徑名作為地址。
type:指定Socket類型。常用的socket類型有SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等。流式Socket(SOCK_STREAM)是一種面向連線的Socket,針對於面向連線的TCP服務套用。數據報式Socket(SOCK_DGRAM)是一種無連線的Socket,對應於無連線的UDP服務套用。
protocol:指定協定。常用協定有IPPROTO_TCP、IPPROTO_UDP、IPPROTO_STCP、IPPROTO_TIPC等,分別對應TCP傳輸協定、UDP傳輸協定、STCP傳輸協定、TIPC傳輸協定。
注意:1.type和protocol不可以隨意組合,如SOCK_STREAM不可以跟IPPROTO_UDP組合。當第三個參數為0時,會自動選擇第二個參數類型對應的默認協定。
2.WindowsSocket下protocol參數中不存在IPPROTO_STCP
返回值:
如果調用成功就返回新創建的套接字的描述符,如果失敗就返回INVALID_SOCKET(Linux下失敗返回-1)。套接字描述符是一個整數類型的值。每個進程的進程空間裡都有一個套接字描述符表,該表中存放著套接字描述符和套接字數據結構的對應關係。該表中有一個欄位存放新創建的套接字的描述符,另一個欄位存放套接字數據結構的地址,因此根據套接字描述符就可以找到其對應的套接字數據結構。每個進程在自己的進程空間裡都有一個套接字描述符表但是套接字數據結構都是在作業系統的核心緩衝里。
綁定
函式原型:
int bind(SOCKET socket, const struct sockaddr* address, socklen_t address_len);
參數說明:
socket:是一個套接字描述符。
address:是一個sockaddr結構指針,該結構中包含了要結合的地址和連線埠號。
address_len:確定address緩衝區的長度。
返回值:
如果函式執行成功,返回值為0,否則為SOCKET_ERROR。
接收
函式原型:
int recv(SOCKET socket, char FAR* buf, int len, int flags);
參數說明:
s ocket:一個標識已連線套接口的描述字。
buf:用於接收數據的緩衝區。
len:緩衝區長度。
flags:指定調用方式。取值:MSG_PEEK 查看當前數據,數據將被複製到緩衝區中,但並不從輸入佇列中刪除;MSG_OOB 處理帶外數據。
返回值:
若無錯誤發生,recv()返回讀入的位元組數。如果連線已中止,返回0。否則的話,返回SOCKET_ERROR錯誤,應用程式可通過WSAGetLastError()獲取相應錯誤代碼。
函式原型:
ssize_t recvfrom(int sockfd, void buf, int len, unsigned int flags, struct socketaddr* from, socket_t* fromlen);
參數說明:
sockfd:標識一個已連線套接口的描述字。
buf:接收數據緩衝區。
len:緩衝區長度。
flags:調用操作方式。是以下一個或者多個標誌的組合體,可通過or操作連在一起:
(1)MSG_DONTWAIT:操作不會被阻塞;
(2)MSG_ERRQUEUE: 指示應該從套接字的錯誤佇列上接收錯誤值,依據不同的協定,錯誤值以某種輔佐性訊息的方式傳遞進來,使用者應該提供足夠大的緩衝區。導致錯誤的原封包通過msg_iovec作為一般的數據來傳遞。導致錯誤的數據報原目標地址作為msg_name被提供。錯誤以sock_extended_err結構形態被使用。
(3)MSG_PEEK:指示數據接收後,在接收佇列中保留原數據,不將其刪除,隨後的讀操作還可以接收相同的數據。
(4)MSG_TRUNC:返回封包的實際長度,即使它比所提供的緩衝區更長, 只對packet套接字有效。
(5)MSG_WAITALL:要求阻塞操作,直到請求得到完整的滿足。然而,如果捕捉到信號,錯誤或者連線斷開發生,或者下次被接收的數據類型不同,仍會返回少於請求量的數據。
(6)MSG_EOR:指示記錄的結束,返回的數據完成一個記錄。
(7)MSG_TRUNC:指明數據報尾部數據已被丟棄,因為它比所提供的緩衝區需要更多的空間。
/*(MSG_TRUNC使用錯誤,4才是MSG_TRUNC的正確解釋)*/
(8)MSG_CTRUNC:指明由於緩衝區空間不足,一些控制數據已被丟棄。
(9)MSG_OOB:指示接收到out-of-band數據(即需要優先處理的數據)。
(10)MSG_ERRQUEUE:指示除了來自套接字錯誤佇列的錯誤外,沒有接收到其它數據。
from:(可選)指針,指向裝有源地址的緩衝區。
fromlen:(可選)指針,指向from緩衝區長度值。
傳送
函式原型:
int sendto( SOCKET s, const char FAR* buf, int size, int flags, const struct sockaddr FAR* to, int tolen);
參數說明:
s:套接字
buf:待傳送數據的緩衝區
size:緩衝區長度
flags:調用方式標誌位, 一般為0, 改變Flags,將會改變Sendto傳送的形式
addr:(可選)指針,指向目的套接字的地址
tolen:addr所指地址的長度
返回值:
如果成功,則返回傳送的位元組數,失敗則返回SOCKET_ERROR。
接收連線請求
函式原型:
int accept( int fd, struct socketaddr* addr, socklen_t* len);
參數說明:
fd:套接字描述符。
addr:返回連線著的地址
len:接收返回地址的緩衝區長度
返回值:
成功返回客戶端的檔案描述符,失敗返回-1。
實例
JAVA
服務端(Server)
客戶端 (Client)
C
服務端(Server):
客戶端 (Client):
PHP
PHP有強大的Socket操作能力,它的處理方式更接近於C,但是沒有C的繁瑣。可以看作是對C操作的Socket的一個封裝。
C#
插槽類型
Socket AM2,原稱“Socket M2”,是供AMD桌上型處理器使用的CPU插座,用以取代Socket 754和939,並已於2006年5月23日推出。它擁有940針,支援雙通道DDR2 SDRAM,但針腳的排列方式與Socket 940不相同,又因為S940不支持DDR2 SDRAM,因此兩者並不兼容。
LGA 1150 插槽,是 Intel 即將發布的第八代產品所採用的插槽,支持CPU新核心 Haswell ,不兼容原有 IVB、SNB 核心的CPU,新版將於2013年發布。
LGA 1155 插槽,是 Intel 平台 7/6 系列主機板採用的插槽,即 Intel Ivy Bridge 核心、Sandy Bridge(新Celeron、新Pentium、第二、三代 i3/i5/i7 處理器採用)。
LGA 2011 ,又稱Socket R,是英特爾(Intel)Sandy Bridge-EX微架構 CPU所使用的CPU接口。LGA2011接口將取代LGA1366接口,成為Intel最新的旗艦產品。
LGA2011接口有2011個觸點,將包含以下新特性:
1、處理器最高可達八核。
2、支持四通道DDR3記憶體。
3、支持PCI-E 3.0規範。
4、晶片組使用單晶片設計,支持兩個SATA 3Gbps和多達十個SATA/SAS 6Gbps接口。
LGA 1567,又稱為Socket LS,是Intel所推出的處理器插座,用於多路(多處理器)伺服器上。其插座有1567個金屬接觸針腳,對應處理器上有1567個金屬觸點。於 2010 年 3 月發布,基於Intel Nehalem架構,核心代號“Beckton”的Intel Xeon-7500系列和Intel Xeon-6500系列的處理器。
Socket 939插槽,是Athlon64處理器所採用的接口類型,針腳數為939針。支持 Socket 939 處理器的主機板只需要4層 PCB。使用普通DDR記憶體。
Socket 940插槽,是Athlon64處理器所採用的接口類型,針腳數為940針。Socket 940接口的處理器支持雙通道ECC記憶體,支持 Socket 940 處理器的主機板必須採用6至9層PCB,必須採用帶ECC校驗的DDR記憶體。
Socket 754插槽,是Athlon64處理器所採用的接口類型,針腳數為754針。Socket 754 接口處理器支持單通道記憶體
LGA 775插槽,是Intel 925X Express和Intel 915 Express晶片組,所採用的接口類型,支持Pentium 4和Pentium 4 Extreme Edition處理器,針腳數為775針。
Socket 478插槽是舊型號Pentium 4系列處理器所採用的接口類型,針腳數為478針。Socket 478的Pentium 4處理器面積很小,其針腳排列極為緊密。採用Socket 478插槽的主機板產品數量眾多,是20世紀套用最為廣泛的插槽類型。
Socket A接口,也叫Socket 462,是目前AMD公司Athlon XP和Duron處理器的插座標準。Socket A接口具有462插空,可以支持133MHz外頻。如同Socket 370一樣,降低了製造成本,簡化了結構設計。
Socket 423插槽是最初Pentium 4處理器的標準接口,Socket 423的外形和前幾種Socket類的插槽類似,對應的CPU針腳數為423。Socket 423插槽多是基於Intel 850晶片組主機板,支持1.3GHz~1.8GHz的Pentium 4處理器。不過隨著DDR記憶體的流行,英特爾又開發了支持SDRAM及DDR記憶體的i845晶片組,CPU插槽也改成了Socket 478,Socket 423插槽也就銷聲匿跡了。
Socket 370架構是英特爾開發出來代替SLOT架構,外觀上與Socket 7非常像,也採用零插拔力插槽,對應的CPU是370針腳。
Socket 370主機板多為採用Intel ZX、BX、i810晶片組的產品,其他廠商有VIA Apollo Pro系列、SIS 530系列等。最初認為,Socket 370的CPU升級能力可能不會太好,所以Socket 370的銷量總是不如SLOT 1接口的主機板。但在英特爾推出的“銅礦”和”圖拉丁”系列CPU, Socket 370接口的主機板一改低端形象,逐漸取代了SLOT 1接口。目前市場中還有極少部分的主機板採用此種插槽。
SLOT 1是英特爾公司為取代Socket 7而開發的CPU接口,並申請的專利。這樣其它廠商就無法生產SLOT 1接口的產品,也就使得AMD、VIA、SIS等公司不得不聯合起來,對Socket 7接口升級,也得到了Super 7接口。後來隨著Super 7接口的興起,英特爾又將SLOT 1結構主機板的製造授權提供給了VIA、SIS、ALI等主機板廠商,所以這些廠商也相應推出了採用SLOT 1接口的系列主機板,豐富了主機板市場。
SLOT 1是英特爾公司為Pentium Ⅱ系列CPU設計的插槽,其將Pentium Ⅱ CPU及其相關控制電路、二級快取都做在一塊子卡上,多數Slot 1主機板使用100MHz外頻。SLOT 1的技術結構比較先進,能提供更大的內部傳輸頻寬和CPU性能。採用SLOT 1接口的主機板晶片組有Intel的BX、i810、i820系列及VIA的Apollo系列,ALI 的Aladdin Pro Ⅱ系列及SIS的620、630系列等。此種接口已經被淘汰,市面上已無此類接口的主機板產品。
SLOT 2用途比較專業,都採用於高端伺服器及圖形工作站的系統。所用的CPU也是很昂貴的Xeon(至強)系列。Slot 2與Slot 1相比,有許多不同。首先,Slot 2插槽更長,CPU本身也都要大一些。其次,Slot 2能夠勝任更高要求的多用途計算處理,這是進入高端企業計算市場的關鍵所在。在當時標準伺服器設計中,一般廠商只能同時在系統中採用兩個 Pentium Ⅱ處理器,而有了Slot 2設計後,可以在一台伺服器中同時採用 8個處理器。而且採用Slot 2接口的Pentium Ⅱ CPU都採用了當時最先進的0.25微米製造工藝。支持SLOT 2接口的主機板晶片組有440GX和450NX。
SLOT A接口類似於英特爾公司的SLOT 1接口,供AMD公司的K7 Athlon使用的。在技術和性能上,SLOT A主機板可完全兼容原有的各種外設擴展卡設備。它使用的並不是Intel的P6 GTL+匯流排協定,而是Digital公司的Alpha匯流排協定EV6。EV6架構是種較先進的架構,它採用多執行緒處理的點到點拓撲結構,支持200MHz的匯流排頻率。支持SLOT A接口結構的主機板晶片組主要有兩種,一種是AMD的AMD 750晶片組,另一種是VIA的Apollo KX133晶片組。此類接口已被Socket A接口全面取代。
Socket 7:Socket在英文裡就是插槽的意思,Socket 7也被叫做Super 7。最初是英特爾公司為Pentium MMX系列CPU設計的插槽,後來英特爾放棄Socket 7接口轉向SLOT 1接口,AMD、VIA、ALI、SIS等廠商仍然沿用此接口,直至發展出Socket A接口。該插槽基本特徵為321插孔,系統使用66MHz的匯流排。Super 7主機板增加了對100MHz外頻和AGP接口類型的支持。
Super 7採用的晶片組有VIA公司的MVP3、MVP4系列,SIS公司的530/540系列及ALI的Aladdin V系列等主機板產品。對應Super 7接口CPU的產品有AMD K6-2、K6-Ⅲ 、Cyrix M2及一些其他廠商的產品。此類接口目前已被淘汰,只有部分老產品才能見到。