## **程序代碼**
`server.php`
```
<?php
// 創建 Server 對象,監聽 127.0.0.1:9501 端口
$server = new swoole_server("127.0.0.1", 9501);
// 監聽連接事件
$server->on('Connect', function ($server, $fd) {
echo "Client: Connect.\n";
});
// 監聽數據接收事件
$server->on('Receive', function ($server, $fd, $from_id, $data) {
$server->send($fd, "Sever: " . $data);
});
// 監聽連接關閉事件
$server->on('Close', function ($server, $fd) {
echo "Client: Close.\n";
});
// 啟動服務器
$server->start();
```
這里就創建了一個`TCP`服務器,監聽本機`9501`端口。它的邏輯很簡單,當客戶端`Socket`通過網絡發送一個`hello`字符串時,服務器會回復一個`Server: hello`字符串。
`Server`是異步服務器,所以是通過監聽事件的方式來編寫程序的。當對應的事件發生時底層會主動回調指定的函數。如當有新的`TCP`連接進入時會執行`onConnect`事件回調,當某個連接向服務器發送數據時會回調`onReceive`函數。
* 服務器可以同時被成千上萬個客戶端連接,`$fd`就是客戶端連接的唯一標識符
* 調用`$server->send()`方法向客戶端連接發送數據,參數就是`$fd`客戶端標識符
* 調用`$server->close()`方法可以強制關閉某個客戶端連接
* 客戶端可能會主動斷開連接,此時會觸發`onClose`事件回調
啟動 `server.php` 查看進程


`telnet/netcat`工具連接服務器



*****
### **參數說明**
#### [創建一個異步`Server`對象](https://wiki.swoole.com/wiki/page/14.html)
* `$host`參數用來指定監聽的ip地址,如`127.0.0.1`,或者外網地址,或者`0.0.0.0`監聽全部地址
* IPv4使用`127.0.0.1`表示監聽本機,`0.0.0.0`表示監聽所有地址
* IPv6使用`::1`表示監聽本機,`::`(相當于`0:0:0:0:0:0:0:0`) 表示監聽所有地址
* `$port`監聽的端口,如`9501`
* 如果`$sock_type`為`UnixSocket Stream/Dgram`,此參數將被忽略
* 監聽小于`1024`端口需要`root`權限
* 如果此端口被占用`server->start`時會失敗
* `$mode`運行的模式
* `SWOOLE_PROCESS`多進程模式(默認)
* `SWOOLE_BASE`基本模式
* `$sock_type`指定`Socket`的類型,支持`TCP`、`UDP`、`TCP6`、`UDP6`、`UnixSocket Stream/Dgram`6種
##### [ **Server->on**](https://wiki.swoole.com/wiki/page/142.html)
注冊`Server`的事件回調函數。
* 第1個參數是回調的名稱, 大小寫不敏感,具體內容參考回調函數列表,事件名稱字符串不要加on
* 第2個函數是回調的`PHP`函數,可以是函數名的字符串,類靜態方法,對象方法數組,匿名函數。
#### [ **Server->set**](https://wiki.swoole.com/wiki/page/13.html)
用于設置運行時的各項參數。服務器啟動后通過`$serv->setting`來訪問`Server->set`方法設置的參數數組。
#### [**onConnect**](https://wiki.swoole.com/wiki/page/49.html)
有新的連接進入時,在worker進程中回調。函數原型:
~~~
function onConnect(swoole_server $server, int $fd, int $reactorId);
~~~
* `$server`是`Swoole\Server`對象
* `$fd`是連接的文件描述符,發送數據/關閉連接時需要此參數
* `$reactorId`來自哪個`Reactor`線程
#### [ **onReceive**](https://wiki.swoole.com/wiki/page/50.html)
接收到數據時回調此函數,發生在worker進程中。函數原型:
~~~
function onReceive(swoole_server $server, int $fd, int $reactor_id, string $data);
~~~
* `$server`,`Server`對象
* `$fd`,`TCP`客戶端連接的唯一標識符
* `$reactor_id`,`TCP`連接所在的`Reactor`線程`ID`
* `$data`,收到的數據內容,可能是文本或者二進制內容
#### [**onClose**](https://wiki.swoole.com/wiki/page/p-event/onClose.html)
TCP客戶端連接關閉后,在worker進程中回調此函數。函數原型:
~~~
function onClose(swoole_server $server, int $fd, int $reactorId);
~~~
* `$server`:`Server`對象
* `$fd`:連接的文件描述符
* `$reactorId`來自那個`reactor`線程,主動`close`關閉時為負數
*****
[關于`$fd`和`$reactorId`](https://wiki.swoole.com/wiki/page/56.html)