1、Socket通常稱為“套接字”,用於描述IP地址和端口,是一個通信鏈的句柄。
2、應用程序通過套接字向網絡發出請求或者應答網絡請求。
3、Socket既不是一個程序,也不是一種協議,其只是操作系統提供的通信層的一組抽象API。
4、進程通信的相關概念:
網間進程通信要解決的是不同主機進程間相互通信問題。為此,首先要解決的是網間進程標識問題。同一主機上,不同進程可用唯一進程號(Process ID)標識。
(1)端口:網絡中可以被命名和尋址的通信端口,是操作系統可分配的一種資源,用於標識通信的進程
傳輸層和網絡層在功能上功能上的最大區別是傳輸層提供進程通信能力。
端口是一種抽象的軟件結構。應用程序(即進程)通過系統調用與某端口建立連接(binding)后,傳輸層傳給該端口的數據都被相應的進程所接收,相應的進程發給傳輸層的數據都通過該端口輸出。

類似於文件描述符,每一個端口都擁有一個端口號,都是整數型標識符,用於區別不同端口。
TCP/UDP段結構中端口的地址都是16比特,有0~65535個端口號。
常見的端口號有,FTP(22)、HTTP(80)、SMTP(25)等。
(2)地址:
網絡通信中通信的兩個進程分別處在不同的機器上,應遵循以下原則:
某台主機可以與多個網絡相連,必須指定一個特定的網絡地址;
網絡上每台主機應有唯一的地址;
每台主機的每個進程應有在該主機上的唯一標識符
(3)連接:
兩個進程間的通信鏈路稱為連接。連接表現為一些緩沖區和一組協議機制。
5、Socket是一種服務,與其實現的語言無關。基於這個性質,我們能實現不同服務之間,不同語言之間的互聯互通。
6、注意一個小知識點:本地進程間通過TCP通信,使用Fiddler等抓包工具是抓不到數據的。主要是因為回環接口的機制,這些包不會到達網卡,數據包直接被返回到傳輸層的輸入隊列中去了。
7、Socket函數原型:
SOCKET socket(int af, int type, int protocol);
af:指定應用程序使用的通信協議的協議族,對於TCP/IP協議族該參數設置為AN_INET,對於UNIX可建立本地Socket
type:指定創建socket類型:
流套接字類型(SOCK_STREAM):最常見的類型,基於TCP協議
數據報套接字類型(SOCK_DGRAM):即UDP數據報
原始套接字類型(SOCK_RAW):在IP層對套接字進行編程
protocol:指定應用程序所使用的通信協議。最常用的是TCP和UDP
流套接字和數據報套接字不能完成的任務,可以在原始套接字中得以實現。
8、Socket從傳輸模式上又分為端對端和點對點的連接,流套接字和數據報套接字都屬於端對端的連接,因此需要綁定端口號。而原始套接字是基於IP協議的,屬於點對點的傳輸模式,是沒有端口這個概念的。比如常用的監測網絡連接ping命令,就是基於ICMP協議的,它不存在端口的概念。
9、PHP中的Socket函數:
(1)socket_create(int $domain, int $type, int $proticol):創建一個socket
第一個參數指定socket創建時所使用的通信協議族 AF_INET(基於IPv4)、AF_INET6(基於IPv6)、AF_UNIX(UNIX本地通信協議)
第二個參數指定socket通信的交互類型,SOCK_STREAM(可靠的全雙工鏈接,支持TCP)、SOCK_DGRAM(自動尋址信息功能,支持UDP)等
第三個參數指定搜才可以使用何種類型處理協議,包括ICMP、UDP、TCP
(2)socket_bind(resource $socket, string $address[, int $port = 0]):將IP地址和端口綁定到socket_create()所創建的句柄
第一個參數是必選參數,其值是socket_create()創建的句柄
第二個參數是必選參數,其值是要綁定的IP地址
第三個參數是可選參數,其值是要綁定的端口號
(3)socket_listen($socket[, $backlog = 0]):用於監聽客戶端數據
第一個參數是socket句柄
第二個參數的允許的最大連接數
(4)socket_set_block($socket):設置為非阻塞模式
(5)socket_write($socket, $buffer[, $length=0]):使用此函數想socket寫入數據
(6)socket_read($socket, $length[, $type = PHP_BINARY_READ]):讀取指定長度的數據
(7)fsockopen($hostname, [$port = -1 [, $errno [, $errstr [$timeout = ini_get["default_socket_timeout"] ]]]) :實現長連接
(8)socket_set_option($socket, $level, $optname, $optval):設置socket的控制選項
(9)socket_last_error([$socket]):返回操作中任何socket產生的最后錯誤,返回值是一個int型的錯誤代號
接下來用PHP創建一個socket例子:
1 <?php 2 $host = "127.0.0.1"; 3 $port = 8880; 4 set_time_limit(0); 5 6 //創建socket 7 $socket = socket_create(AF_INET, SOCK_STREAM, 0) or die('create error'); 8 9 //綁定socket到指定端口 10 $result = socket_bind($socket, $host) or die('bind error'); 11 12 //開始監聽連接 13 $result = socket_listen($socket, 3) or die('listen error'); 14 15 //接收連接請求並調用另一個子socket處理客戶端——服務器間的信息 16 $spawn = socket_accept($socket) or die('accept error'); 17 18 //讀取客戶端輸入 19 $input = socket_read($spawn, 1024) or die('spawn read error'); 20 21 $output = "我是返回的數據"; 22 //返回服務端 23 socket_write($spawn, $output, strlen($output)) or die('write error'); 24 25 //關閉socket 26 socket_close($socket); 27 socket_close($$spawn); 28 ?>
