Unix網絡編程 之 socket簡介
概述
Socket的英文原意是“孔”或“插座”,現在,作為Unix的進程通信機製,常常取“插座”這一意義。日常生活中常見的插座,有的是信號插座,有的是電源插座,有的可以接收信號或能量,有的可以發送信號或能量。舉例來說,電話線與電話機之間需要一個插座(相當於兩者之間的接口,這一部分裝置物理上是存在的)。對於網絡編程,socket就相當於電話線與電話機之間的插座。
將電話係統與麵向連接的Socket機製相比,兩者之間有著驚人的相似的地方。以一個國家的電話網為例。電話的通信雙方相當於互相通信的兩個進程;通話雙方所在的地區(享有一個全局唯一的區號)相當於一個網絡,區號即是其網絡地址;區內的一個單位的交換機相當於一台主機,交換機分配給每個用戶的局內號碼就相當於主機運行中分配給進程的socket號。
任何用戶在通話之前,首先應該有一部電話機,相當於申請一個socket號;同時,還必須直到對方的電話號碼,此電話號碼對應於對方的電話機,該電話機也必須申請一個socket號。申請socket號的過程就是將電話線插入電話機的通信串口的過程。然後,用戶撥號唿叫對方,此時相當於發出連接請求(如果對方不在本地區,在對方電話號碼前還應該附加上對方所在地區的區號,此區號相當於給出網絡地址)。如果對方在電話機處並且空閑(相當於通信的目的主機開機且可以接受連接請求),拿起電話話筒,雙方就可以正是通話,即連接成功。雙方通話的過程,是電話機通過接口發送信號和從接口接收信號的過程,相當於向socket發送數據和從socket接收數據。當通話結束後,一方掛機,相當於接口阻塞,socket關閉,從而撤銷連接。
在電話係統中,一般用戶隻能感受到本地電話機和對方電話號碼的存在,建立通話的過程、話音傳輸的過程以及整個電話係統的技術細節對用戶而言是封裝的,不透明的,用戶與用戶之間的電話僅通過通信協議和電話號碼實現。這一機製與socket機製非常相似。socket利用網絡通信設施實現進程間通信,但它對於通信設施的具體細節並不關心,隻要底層通信設施能夠提供足夠的通信能力,socket便能夠進行基本的網絡通信功能。
至此,我們隊socket進行了直觀的描述。抽象出來,socket實質上提供了進程間通信的端點。進程通信之前,雙方首先必須各自創建一個端點,否則是沒法建立聯係並相互通信的。正如電話係統一樣,雙方的通話是建立在通話雙方均各自擁有一台電話機一樣。
每一個socket都用一個半相關描述:
socket(通信協議,本地地址,本地端口);
一個完整的socket則用一個相關描述:
socket(通信協議,本地地址,本地端口,遠程地址,遠程端口);
每一個socket都有一個本地唯一的socket號,該socket號由操作係統進行分配和管理。
最重要的是,socket是麵向客戶端/服務器模型而設計的,針對客戶端和服務器程序提供不同的socket係統調用。客戶端隨機申請一個socket號(相當於一個想打電話的人可以在任何一部入網的電話機上撥號唿叫);服務器擁有公認的socket,任何客戶都可以向它發出連接請求和信心傳輸請求(相當於一個被叫電話擁有一個唿叫方知道的電話號碼)。
Socket利用客戶端/服務器模型巧妙地解決了進程之間建立通信連接的問題。服務器socket為眾所周知且非常重要的。無論如何,通信雙方至少有一方知道對方的socket信息(主要指網絡地址和端口號)。
套接字的類型及對應流程
傳輸層協議主要分為TCP協議和UDP協議。由TCP向應用程序提供的服務不同於UDP提供的服務。
首先,TCP提供客戶端和服務器之間的連接(connection)。TCP客戶端先與某個給定服務器建立一個連接,再跨該連接與服務器交換數據,然後終止該連接。
其次,TCP提供可靠性(reliability)。當TCP向另一端發送數據時,它要求對端返回確認信息,如果沒有收到確認,TCP就自動重傳數據並等待更長時間。在數次重傳失敗後,TCP才放棄。
再則,TCP提供流量控製(flow control)。
最後,TCP連接是全雙工的,這意味著一個給定的連接上應用可以在任何時刻在進出兩個方向上發送和接收數據。
套接字有三種類型:流式套接字(SOCK_STREAM)、數據報套接字(SOCK_DGRAM)和原始套接字。
1、SOCK_STREAM(TCP適用)
流式套接字(SOCK_STREAM)提供可靠的、麵向連接的通信。其使用了TCP協議。
其建立連接與傳輸的過程如下圖:
2、SOCK_DGRAM(UDP適用)
數據報套接字(SOCK_DGRAM)定義了一種無連接的服務,數據通過相互獨立的報文進行傳輸,是無序的,並且不保證可靠性。
數據報套接字為什麼“無連接”和“不可靠”?
*發送的數據報可能不會到達指定目的主機;
*數據報可能會以不同順序到達;
*到達目的主機的數據報可能存在錯誤。
數據報套接字使用UDP協議。
其數據傳輸流程如下圖:
3、原始套接字
原始套接字主要用於一些協議的開發,可以進行比較底層的操作。它功能強大,但是沒有上麵介紹的兩種套接字使用方便,一般的程序也涉及不到原始套接字。
套接字描述符
1、什麼是套接字?
套接字是通過標準的unix文件描述符與其它的程序進行通信的一種方法(其它的進程間通信方法包括管道等)。
2、Socket描述符
在Unix係統中,任何對I/O的操作,都是通過讀或寫一個文件描述符來實現的。一個文件描述符隻是一個簡單的整形數值,代表一個被打開的文件(這裏的文件是廣義上的文件,並不隻是代表磁盤文件,而且代表一個網絡連接,一個先進先出的隊列,一個終端顯示屏幕以及其它的一切)。在Unix係統中,任何東西都是文件。
因此,在這裏,我們應該建立這樣一種概念,那就是socket是文件,socket描述符是文件描述符。
最後更新:2017-04-03 05:39:53