## **程序代码**
`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` 查看进程
![](https://img.kancloud.cn/ff/5f/ff5f8295280cb7a1ba115afacfd5b8c9_2878x1432.png)
![](https://img.kancloud.cn/f2/8c/f28cbbc8106d5088fd75eaa02108ebc4_2874x810.png)
`telnet/netcat`工具连接服务器
![](https://img.kancloud.cn/c8/97/c89705ba144e174872951d30ad1c088d_2878x496.png)
![](https://img.kancloud.cn/5b/ce/5bce3ed1267219a70f87000c596a851b_2864x508.png)
![](https://img.kancloud.cn/7b/b7/7bb714e56571b6034574eddd78048045_2878x292.png)
*****
### **参数说明**
#### [创建一个异步`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)