1 . socket_create
创建一个套接字(通讯节点)
resource socket_create ( int $domain , int $type , int $protocol )
创建并返回一个套接字,也称作一个通讯节点。一个典型的网络连接由 2 个套接字构成,一个运行在客户端,另一个运行在服务器端。
参数
domain 参数指定哪个协议用在当前套接字上。
AF_INET IPv4 网络协议。TCP 和 UDP 都可使用此协议。
AF_INET6 IPv6 网络协议。TCP 和 UDP 都可使用此协议。
AF_UNIX 本地通讯协议。具有高性能和低成本的 IPC(进程间通讯)。type 参数用于选择套接字使用的类型。
SOCK_STREAM 提供一个顺序化的、可靠的、全双工的、基于连接的字节流。支持数据传送流量控制机制。TCP 协议即基于这种流式套接字。
SOCK_DGRAM 提供数据报文的支持。(无连接,不可靠、固定最大长度).UDP协议即基于这种数据报文套接字。
SOCK_SEQPACKET 提供一个顺序化的、可靠的、全双工的、面向连接的、固定最大长度的数据通信;数据端通过接收每一个数据段来读取整个数据包。
SOCK_RAW 提供读取原始的网络协议。这种特殊的套接字可用于手工构建任意类型的协议。一般使用这个套接字来实现 ICMP 请求(例如 ping)。
SOCK_RDM 提供一个可靠的数据层,但不保证到达顺序。一般的操作系统都未实现此功能。
- protocol 参数,是设置指定 domain 套接字下的具体协议。这个值可以使用 getprotobyname() 函数进行读取。如果所需的协议是 TCP 或 UDP,可以直接使用常量 SOL_TCP 和 SOL_UDP 。
icmp Internet Control Message Protocol 主要用于网关和主机报告错误的数据通信。例如“ping”命令(在目前大部分的操作系统中)就是使用 ICMP 协议实现的。
udp User Datagram Protocol 是一个无连接的、不可靠的、具有固定最大长度的报文协议。由于这些特性,UDP 协议拥有最小的协议开销。
tcp Transmission Control Protocol 是一个可靠的、基于连接的、面向数据流的全双工协议。TCP 能够保障所有的数据包是按照其发送顺序而接收的。如果任意数据包在通讯时丢失,TCP 将自动重发数据包直到目标主机应答已接收。因为可靠性和性能的原因,TCP 在数据传输层使用 8bit 字节边界。因此,TCP 应用程序必须允许传送部分报文的可能。
返回值
socket_create() 正确时返回一个套接字,失败时返回 FALSE。要读取错误代码,可以调用 socket_last_error()。这个错误代码可以通过 socket_strerror() 读取文字的错误说明
$this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
2 . socket_set_block
阻塞或非阻塞模式的设置
socket_set_block($this->socket);
3 . socket_set_option
给套接字设置数据流选项
bool socket_set_option ( resource $socket , int $level , int $optname , mixed $optval )
参数1:socket_create或者socket_accept的函数返回值
参数2:SOL_SOCKET,只有这个选项
参数3可为:SO_REUSEADDR SO_RCVTIMEO S0_SNDTIMEO
参数4:
- 参数3为SO_REUSEADDR: true或者false
- 参数3为SO_RCVTIMEO或SO_SNDTIMEO:数组array(‘sec’=>1,’usec’=>500000) 设置超时的最大时间,一个是秒为单位,一个是微秒单位,作用都一样
socket_set_option($this->socket, SOL_SOCKET, SO_SNDTIMEO, array('sec' => $timeout, 'usec' => 0));
socket_set_option($this->socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => $timeout, 'usec' => 0));
socket_set_option($this->socket, SOL_SOCKET, SO_SNDBUF, 0);
socket_set_option($this->socket, SOL_SOCKET, SO_RCVBUF, 0);
4 . socket_shutdown
bool socket_shutdown ( resource $socket [, int $how = 2 ] )
通常来说,socket是双向的,即数据是双向通信的。但有些时候,你会想在socket上实现单向的socket,即数据往一个方向传输。
单向的socket便称为半开放Socket。要实现半开放式,需要用到shutdown()函数。
一般来说,半开放socket适用于以下场合:
(1)当你想要确保所有写好的数据已经发送成功时。如果在发送数据的过程中,网络意外断开或者出现异常,系统不一定会返回异常,这是你可能以为对端已经接收到数据了。这时需要用shutdown()来确定数据是否发送成功,因为调用shutdown()时只有在缓存中的数据全部发送成功后才会返回。
(2)想用一种方法来捕获程序潜在的错误,这错误可能是因为往一个不能写的socket上写数据,也有可能是在一个不该读操作的socket上读数据。当程序尝试这样做时,将会捕获到一个异常,捕获异常对于程序排错来说是相对简单和省劲的。
(3)当您的程序使用了fork()或者使用多线程时,你想防止其他线程或进程访问到该资源,又或者你想立刻关闭这个socket,那么可以用shutdown()来实现。
另外说一下,如果调用了Close()函数,程序中只是确保了对于某个特定的进程或线程来说,该连接是关闭的;但socket只有在所有的进程调用了Close()或者socket超出了工作范围时,才会真正的被关闭或删除。而如果想立刻关闭socket,那么可以通过shutdown()来实现。
shutdown()的调用是需要一个参数:0代表禁止下次的数据读取;1代表禁止下次的数据写入;2代表禁止下次的数据读取和写入。
同时,shutdown()的效果是累计的,不可逆转的。既如果关闭了一个方向数据传输,那么这个方向将会被关闭直至完全被关闭或删除,而不能重新被打开。如果第一次调用了shutdown(0),第二次调用了shutdown(1),那么这时的效果就相当于shutdown(2),也就是双向关闭socket。
5 . socket_close
关闭
void socket_close ( resource $socket )
6 . socket_connect
开启一个套接字连接
bool socket_connect ( resource $socket , string $address [, int $port = 0 ] )
$conn = socket_connect($this->socket, $host, $port);
7 . socket_write
写入套接字
int socket_write ( resource $socket , string $buffer [, int $length ] )
- 参数
- socket
- buffer
要写入缓冲区的字符串 - length
可选参数length可以指定备用套接字写入的字节长度。如果这个长度大于缓冲区的长度,它默默地截断为缓冲区的长度
8 . socket_read()
读取指定长度的数据
string socket_read ( resource $socket , int $length [, int $type = PHP_BINARY_READ ] )
- PHP_BINARY_READ (Default) - use the system recv() function. Safe for reading binary data.
- PHP_NORMAL_READ - reading stops at \n or \r.
9 . socket_connect — 开启一个套接字连接
bool socket_connect ( resource $socket , string $address [, int $port = 0 ] )
- 参数
- socket
- address 如果参数 socket 是 AF_INET , 那么参数 address 则可以是一个点分四组表示法(例如 127.0.0.1 ) 的 IPv4 地址; 如果支持 IPv6 并且 socket 是 AF_INET6,那么 address 也可以是有效的 IPv6 地址(例如 ::1);如果套接字类型为 AF_UNIX ,那么 address 也可以是一个Unix 套接字。
- port 参数 port 仅仅用于 AF_INET 和 AF_INET6 套接字连接的时候,并且是在此情况下是需要强制说明连接对应的远程服务器上的端口号。
$conn = socket_connect($this->socket, $host, $port);
图示