创建TCP服务器

程序代码

server.php

//创建Server对象,监听 127.0.0.1:9501端口
$serv = new swoole_server("127.0.0.1", 9501); 

//监听连接进入事件
$serv->on('connect', function ($serv, $fd) {  
    echo "Client: Connect.\n";
});

//监听数据接收事件
$serv->on('receive', function ($serv, $fd, $from_id, $data) {
    $serv->send($fd, "Server: ".$data);
});

//监听连接关闭事件
$serv->on('close', function ($serv, $fd) {
    echo "Client: Close.\n";
});

//启动服务器
$serv->start(); 

这里就创建了一个TCP服务器,监听本机9501端口。它的逻辑很简单,当客户端Socket通过网络发送一个 hello 字符串时,服务器会回复一个 Server: hello 字符串。

swoole_server是异步服务器,所以是通过监听事件的方式来编写程序的。当对应的事件发生时底层会主动回调指定的PHP函数。如当有新的TCP连接进入时会执行onConnect事件回调,当某个连接向服务器发送数据时会回调onReceive函数。

  • 服务器可以同时被成千上万个客户端连接,$fd就是客户端连接的唯一标识符
  • 调用 $server->send() 方法向客户端连接发送数据,参数就是$fd客户端标识符
  • 调用 $server->close() 方法可以强制关闭某个客户端连接
  • 客户端可能会主动断开连接,此时会触发onClose事件回调

执行程序

php server.php

在命令行下运行server.php程序,启动成功后可以使用 netstat 工具看到,已经在监听9501端口。这时就可以使用telnet/netcat工具连接服务器。

telnet 127.0.0.1 9501
hello
Server: hello

无法连接到服务器的简单检测手段

  • Linux下,使用netstat -an | grep 端口,查看端口是否已经被打开处于Listening状态
  • 上一步确认后,检查防火墙问题
  • 注意服务器所使用的IP地址,如果是127.0.0.1回环地址,则客户端只能使用127.0.0.1才能连接上

  • 王浩

    servic.php 启动了但是 怎么连接啊 我链接不上 求解

  • 小白

    运行之后什么反应也没有 卡住了

  • 不曾远去

    不是卡住了,是已经开始运行了,你新开一个窗口,运行命令telnet 127.0.0.1 9501 就可以跟他通信了

  • tb

    ctrl+】退出当前 close 关闭telnet ?帮助 quit直接退出 root@tb:/home/tb# telnet 127.0.0.1 9501 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. quit server: quit ^] telnet> quit Connection closed.

  • 小夏

    我运行的时候,为什么提示的是 Class 'swoole_server' not found 这个扩展我已经安装了,为什么还提示。

  • 小夏

    已解决

  • backer

    telnet那一步被服务器拒绝了,端口已被程序运行了,

  • backer

    自己犯二了,已解决

  • 李海波

    怎么关闭,不会用kill -9 一个一个的杀吧?

  • 羊毛先生

    应用场景是?

  • 打酱油的程序员

    如果不定义receive事件,就不会真正的监听端口,这算不算bug?

  • 不经意的岁月

    执行后并没有监听端口,这个是什么原因

  • 境静

    你怎么解决的 我也遇到相同的问题啦

  • 肖玉琴

    我挺顺利的额

  • 疯狂的Camaro

    Administrator@HZZ9-20160319GJ /home/swoole/mytest $ php server.php Client: Connect. Client: Close. Client: Connect. Client: Close. Client: Connect.

    //这是用telnet连接服务器的但是我输入hello没有出来任何东西啊 Administrator@HZZ9-20160319GJ /home/swoole/mytest $ telnet 127.0.0.1 9501 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. hello

    求各位大神帮我看看

  • 1234

    你直接在浏览器访问的吧?貌似这是client使用的。。。

  • 赵哲

    示例代码监听的是127.0.0.1,只能在本机访问。如果想在其他机器访问,可以修改为0.0.0.0

  • 骑猪看月赏嫦娥

    怎么退出的?

  • 星语

    怎么解决的啊

  • 星语

    怎么解决的

  • cheng_bifeng

    中文乱码怎么解决?

  • ぐ 乄志

    $fd是指的什么,上面的示例程序可以直接运行吗

  • ぐ 乄志

    虽然运行成功了但是还是不知道具体参数是什么意思,有没有稍微具体一点的文档呢

  • 江恒

    顺利实现,第一步已经迈出

  • 坐凳看你吃薯片

    telnet 127.0.0.1 9501 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. ^] telnet> quit Connection closed. 第一步好艰难,php版本要在5.3.10+[可怜]

  • 序状

    [2017-02-09 16:01:56 @4602.0] WARNING swSocket_bind: bind(127.0.0.1:0) failed. Error: Address already in use [98] 报这个错误,是什么意思啊

  • 薛杰明

    被占用了或者已经在监控中

  • 慧空

    请问 这个怎么解决的 谢谢

  • 慧空

    哦 原来我的服务器安装了 php7 但swoole 装到了 php5上 php -i | grep php.ini 显示的是这个路径 我加上extension=swool.so 后 依旧 不管用 php -m 依旧查不到加载的 后来php5 -m 发现了 swoole

  • 麦子时光

    php server.php 应该有什么反应

  • snail

    就是卡住的样子,实际已经运行成功。另外开一个终端然后运行: telnet 127.0.0.1 9501
    这样就链接成功了。

  • 雲淡風輕

    telnet连接推送接受数据都成功,但是和非swoole的客户端通信的时候,连接上服务端可以推送数据给客户端,但是客户端给服务端发送却收不到,好像是压根没触发onreceive,但是客户端和go写的服务端可以,请问这是怎么回事?

  • 零碎の歡顔

    第一次启动 server.php 没问题 在中途强制退出了服务器这个脚本之后,之后运行服务器脚本一直报这个错误 WARNING swSocket_bind: bind(0.0.0.0:9501) failed. Error: Address already in use [98] 端口已经被占用,该怎么解决呢

  • 风一样的男子

    查看打开9501端口的工具

    lsof -i:9501

    强制删除进程

    kill -9 X端口号X

  • mac 环境下 telnet时 报错: ERROR swReactorKqueue_wait(:332): kqueue event read socket#6 handler failed. Error: Invalid argument[22] 什么原因呢?

  • @哋瓜僷㊣

    php.ini中已经有swoole了,但是运行不了server.php

  • 蓝天白云

    telnet退出可以按CTRL+]然后输入quit就行。

  • 谈天说地

    疯狂的Camaro

    Administrator@HZZ9-20160319GJ /home/swoole/mytest $ php server.php Client: Connect. Client: Close. Client: Connect. Client: Close. Client: Connect.

    //这是用telnet连接服务器的但是我输入hello没有出来任何东西啊 Administrator@HZZ9-20160319GJ /home/swoole/mytest $ telnet 127.0.0.1 9501 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. hello

    求各位大神帮我看看----跟这个问题一样,一直都是php web开发,不知道这个问题在哪里,又没报错,又没反应。

  • 谈天说地

    使用同步tcp报错为recv() failed. Error: Resource temporarily unavailable [11],这是什么原因?哪里错了?

  • 爱拼才会赢

    就是这么厉害啊

  • 谈天说地

    [root@VM_171_207_centos ~]# /etc/init.d/iptables status Table: filter Chain INPUT (policy ACCEPT) num target prot opt source destination
    1 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:9501 防火墙也是开启了该端口的,不知道哪里出问题了!

  • 谈天说地

    [root@VM_171_207_centos ~]# /etc/init.d/iptables status Table: filter Chain INPUT (policy ACCEPT) num target prot opt source destination
    1 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:9501 防火墙也是开启了该端口的,不知道哪里出问题了!

  • 昃昃

    最后检查防火墙设置,怎么设置呀?我的外网访问服务器ip:端口号总是连接不上?怎么设置呀

  • wowo

    想问下为什么程序运行之后,会启动4个进程(我通过ps aux看到的),但是通过netstat只能杀掉一个,其他三个仍然存在。

  • KK

    [2017-10-16 14:18:13 #5235.2] ERROR swServer_master_onAccept (ERROR 502): accept() failed. Error: Too many open files[24] 并发1000,第976个之后出现这个错误

  • KK

    知道了,ulimit没设置

  • FUNCO_小风

    为了避免出错和代码可读性,swoole的库能不能提供recieve close这种字符串的define或者static定义