这是一篇我在做PHP Web开发时,发表于2020年9月15日某平台的学习随记,关于如何使用PHP语言建立一个简单的socket通信,现转载至B站。
【资料图】
Socket编程
Socket函数
PHP提供了两种API,一种内置在PHP内核中,作为主动连接而无法实现端口监听相关功能;另一种是外部PECL扩展库,支持监听和交互模式。
内置Socket函数
包括fsockopen和pfsockopen。
fsockopen()其功能是初始化一个socket套接字并连接到目标主机(hosthome)。
pfsockopen()是实现持久化连接,也被称为长连接。
两者唯一的区别就是建立长连接,即客户端与服务器端建立连接后不再断开,完成报文的发送与接收后再断开。
两者执行后都会返回一个资源编号,可以使用所有文件操作函数对其进行操作,
fsockopen负责创建socket连接,fwrite负责发送数据,fread负责接收数据,类似于从文件流中读/写。
上面是基于TCP协议的socket连接,而要创建UDP socket连接,则需要:
该流包装器内可以换为tcp://,可以概括为通用的语法来概括socket地址:
PECL socket 函数库
使用如下方法安装Socket扩展,
该扩展库有这些函数。
1. socket_create
Protocol协议值和说明
AF_INET 大多数适用,适用TCP或UDP传输,使用IPv4地址。
AF_INET6 使用IPv6地址。
AF_UNIX 较少使用,用于Unix和Linux系统,一般为客户端和服务器在同一台的情况下使用。
Socket通信类型
SOCK_STREAM 按照顺序的、可靠的、数据完整的、基于字节流的连接。使用最多,适用于TCP传输
SOCK_DGRAM 无连接的、固定长度的传输调用。不可靠,使用UDP进行连接。
SOCK_SEQPACKET 双线路的、可靠的连接,发送固定长度的数据包进行传输,必须把这个包完整地接受才能进行读取。
SOCK_RAW 提供单一网络访问,使用ICMP公共协议。
SOCK_RDM 很少使用。
Socket处理协议类型
ICMP 互联网控制消息协议,主要使用在网关和主机上,用来检查网络状况和报告错误信息。
UDP 用户数据报文协议,无连接、不可靠的传输协议。
TCP 传输控制协议,使用最多、可靠的公共协议,能保证数据包到达接受者那里,如果在传输过程中错误,那么它将重新发送出错数据包。
2. socket_bind
用于将IP和端口绑定在socket_create所创建的资源中。
注意,在address中,如果套接字是AF_INET,那么address必须是一个四点分法 的IPv4地址(例如);如果套接字是AF_UNIX,那么address是Unix/Linux套接字的一部分(例如/tmp/)。
参数prot仅仅用于AF_INET套接字连接的时候,并且指定连接中需要监听的端口号。
3. socket_listen
在绑定Socket后,服务器端使用此函数监听客户端数据。
backlog是可选项,表示允许的最大连接数。
4. socket_set_block
设置为非阻塞模式。
当设置为非阻塞模式后,会立即返回。与其对应的就是阻塞模式,也就是没有完成任务不能返回,直到对方有反馈才继续下一步处理。
当用户连接较多时,非阻塞模式是必要的。
5. socket_write
此函数只是向socket资源写数据,并没有执行发送操作。
6. socket_send
发送数据。
7. socket_read
从socket中读取指定长度的数据。
第三个参数指的是要读区数据的类型,默认PHP_BINARY_READ,也就是安全读取二进制数据;另一个值可以是PHP_NORMAL_READ,当读取到“\r”“\n”换行符时停止。
8. socket_set_option
此函数用来设置socket的控制选项。
bool socket_set_option(resource $socket, int $optname, mixed $optval);
例如,用该函数设置发送超时时间为2s,接收超时时间为3s。
9. socket_last_error
其返回任何socket操作中的函数生成的最后错误信息,其返回值为一个整型值的错误代号。
它能够帮助我们在处理错误时找到原因。
建立TCP Socket客户端
客户端是通信的发起者,而服务器程序负责被动等待客户端发起通信,并对其做出响应。
1. 连接TCP服务器
使用socket_connect函数。
当运行此脚本时,输出为:
另外,连接类型为TCP表示可靠的数据流,可以有多个这样的数据流,但彼此不受干扰。而其他协议如UDP、ICKMP、ARP则是非可靠的连接。也就是说,你可以一直接收和发送下去。
2. 发送数据
使用socket_send来发送数据。
创建 TCP Socket服务器
在服务器端使用命令行方式运行,在Linux中可用如下命令
也可以在系统守护进程中运行
通过使用以下命令杀死上面的进程
如果只创建一个TCP服务器实例,可以直接使用函数socket_create_listen()。
创建UDP服务器
UDP因为连接次数较少,处理比YCP简单,一个UDP服务器只需要等待接收少量数据,与客户端在一个socket中发送数据而无需连接。
该UDP服务器可以处理多个客户,但只是简单地处理输入后的返回信息。