Socket進程通訊機制

一、Socket一般稱爲「套接字」,用於描述IP地址和端口,是一個通訊鏈的句柄php

二、應用程序經過套接字向網絡發出請求或者應答網絡請求。編程

三、Socket既不是一個程序,也不是一種協議,其只是操做系統提供的通訊層的一組抽象API。服務器

四、進程通訊的相關概念:網絡

  網間進程通訊要解決的是不一樣主機進程間相互通訊問題。爲此,首先要解決的是網間進程標識問題。同一主機上,不一樣進程可用惟一進程號(Process ID)標識。dom

  (1)端口:網絡中能夠被命名和尋址的通訊端口,是操做系統可分配的一種資源,用於標識通訊的進程socket

    傳輸層和網絡層在功能上功能上的最大區別傳輸層提供進程通訊能力函數

    端口是一種抽象的軟件結構。應用程序(即進程)經過系統調用與某端口創建鏈接(binding)後,傳輸層傳給該端口的數據都被相應的進程所接收,相應的進程發給傳輸層的數據都經過該端口輸出。工具

    

  

      相似於文件描述符,每個端口都擁有一個端口號,都是整數型標識符,用於區別不一樣端口。spa

      TCP/UDP段結構中端口的地址都是16比特,有0~65535個端口號。操作系統

      常見的端口號有,FTP(22)、HTTP(80)、SMTP(25)等。

  (2)地址:

      網絡通訊中通訊的兩個進程分別處在不一樣的機器上,應遵循如下原則:

        某臺主機能夠與多個網絡相連,必須指定一個特定的網絡地址;

        網絡上每臺主機應有惟一的地址;

        每臺主機的每一個進程應有在該主機上的惟一標識符

  (3)鏈接:

      兩個進程間的通訊鏈路稱爲鏈接。鏈接表現爲一些緩衝區和一組協議機制。

 

五、Socket是一種服務,與其實現的語言無關。基於這個性質,咱們能實現不一樣服務之間,不一樣語言之間的互聯互通。

 

六、注意一個小知識點:本地進程間經過TCP通訊,使用Fiddler等抓包工具是抓不到數據的。主要是由於迴環接口的機制,這些包不會到達網卡,數據包直接被返回到傳輸層的輸入隊列中去了。

 

七、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

  流套接字和數據報套接字不能完成的任務,能夠在原始套接字中得以實現。

 

八、Socket從傳輸模式上又分爲端對端和點對點的鏈接,流套接字和數據報套接字都屬於端對端的鏈接,所以須要綁定端口號。而原始套接字是基於IP協議的,屬於點對點的傳輸模式,是沒有端口這個概念的。好比經常使用的監測網絡鏈接ping命令,就是基於ICMP協議的,它不存在端口的概念。

 

九、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 ?>
相關文章
相關標籤/搜索