百科狗-知识改变命运!
--

socket_create() - socket通信函数

百变鹏仔12个月前 (11-21)阅读数 49#技术干货
文章标签协议

socket_create()

(PHP 4 >= 4.1.0, PHP 5, PHP 7)

创建一个套接字(通讯节点)

说明

socket_create(int $domain,int $type,int $protocol): resource

创建并返回一个套接字,也称作一个通讯节点。一个典型的网络连接由 2 个套接字构成,一个运行在客户端,另一个运行在服务器端。

参数

$domain

$domain参数指定哪个协议用在当前套接字上。

可用的地址/协议
Domain描述
AF_INET IPv4 网络协议。TCP 和 UDP 都可使用此协议。
AF_INET6 IPv6 网络协议。TCP 和 UDP 都可使用此协议。
AF_UNIX本地通讯协议。具有高性能和低成本的 IPC(进程间通讯)。
$type

$type参数用于选择套接字使用的类型。

可用的套接字类型
类型描述
SOCK_STREAM提供一个顺序化的、可靠的、全双工的、基于连接的字节流。支持数据传送流量控制机制。TCP 协议即基于这种流式套接字。
SOCK_DGRAM提供数据报文的支持。(无连接,不可靠、固定最大长度).UDP协议即基于这种数据报文套接字。
SOCK_SEQPACKET提供一个顺序化的、可靠的、全双工的、面向连接的、固定最大长度的数据通信;数据端通过接收每一个数据段来读取整个数据包。
SOCK_RAW提供读取原始的网络协议。这种特殊的套接字可用于手工构建任意类型的协议。一般使用这个套接字来实现 ICMP 请求(例如 ping)。
SOCK_RDM提供一个可靠的数据层,但不保证到达顺序。一般的操作系统都未实现此功能。
$protocol

socket_create() - socket通信函数

$protocol参数,是设置指定$domain套接字下的具体协议。这个值可以使用getprotobyname()函数进行读取。如果所需的协议是 TCP 或 UDP,可以直接使用常量SOL_TCPSOL_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()读取文字的错误说明。

更新日志

版本说明
5.0.0增加AF_INET6支持。

错误/异常

如果使用一个无效的$domain或$type,socket_create()会使用AF_INETSOCK_STREAM替代无效参数,同时会发出E_WARNING警告信息。

参见

  • socket_accept()接受套接字上的连接
  • socket_bind()给套接字绑定名字
  • socket_connect()开启一个套接字连接
  • socket_listen()监听一个套接字的连接
  • socket_last_error()返回套接字上的最后一个错误
  • socket_strerror()返回一个描述套接字错误的字符串
Took me about 20 minutes to figure out the proper arguments to supply for a AF_UNIX socket. Anything else, and I would get a PHP warning about the 'type' not being supported. I hope this saves someone else time. 
It took some time to understand how one PHP process can communicate with another by means of unix udp sockets. Examples of 'server' and 'client' code are given below. Server is assumed to run before client starts.
'Server' code

'Client' code 
Note that if you create a socket with AF_UNIX, a file will be created in the filesystem. This file is not removed when you call socket_close - you should unlink the file after you close the socket.
Please be aware that RAW sockets (as used for the ping example) are restricted to root accounts on *nix systems. Since web servers hardly ever run as root, they won't work on webpages.
On Windows based servers it should work regardless.
Okay I talked with Richard a little (via e-mail). We agree that getprotobyname() and using the constants should be the same in functionality and speed, the use of one or the other is merely coding style. Personally, we both think the constants are prettier :).
The eight different protocols are the ones implemented in PHP- not the total number in existance (RFC 1340 has 98).
All we disagree on is using 0- Richard says that "accordning to the official unix/bsd sockets 0 is more than fine." I think that since 0 is a reserved number according to RFC 1320, and when used usually refers to IP, not one of it's sub-protocols (TCP, UDP, etc.)
I've written the ping() function using socket_create() with SOCK_RAW.
(on Unix System, you need to have the root acces to execute this function) 
Here is a ping function for PHP without using exec/system/passthrough/etc... Very useful to use to just test if a host is online before attempting to connect to it. Timeout is in seconds. 
Here's a ping function that uses sockets instead of exec(). Note: I was unable to get socket_create() to work without running from CLI as root. I've already calculated the package's checksum to simplify the code (the message is 'ping' but it doesn't actually matter). 
On UNIX systems php needs /etc/protocols for constants like SOL_UDP and SOL_TCP.
This file was missing on my embedded platform.
Seems there aren't any examples of UDP clients out there. This is a tftp client. I hope this makes someone's life easier. 
Sometimes when you are running CLI, you need to know your own ip address. 
Here's a solution for icmpv6 ping with php, dropping it here in case if someone has problems with icmpv6 with php.
内容声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。部分内容参考包括:(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供参考使用,不准确地方联系删除处理!本站为非盈利性质站点,本着为中国教育事业出一份力,发布内容不收取任何费用也不接任何广告!)