Socket编程 之 Socket函数简介
说明:文章截选自实验楼教程【PHP Socket编程】,该教程由用户“水煮牛肉”发布在实验楼上,未经允许,禁止转载;
Socket简介
许多第一次接触 Socket 编程的同学并不知道 Socket 是什么意思,就算知道它的翻译 “套接字” 也不明白这到底是个什么东西。其实 Socket 还有一个意思,就是 “插座”,根据这个意思来理解抽象的 “套接字” 会容易得多,创建 Socket 就是装一个插座,为电器提供电能服务,用各种电气标准把它们连接起来
先来一段程序跑起来, 再逐一解释每个函数的使用方法,及参数释义
// server.php
<?php
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($sock, "127.0.0.1", 80);
socket_listen($sock);
for ( ; ; ) {
$conn = socket_accept($sock);
$write_buffer = "HTTP/1.0 200 OK\r\nServer: my_server\r\nContent-Type: text/html; charset=utf-8\r\n\r\nhello!world";
socket_write($conn, $write_buffer);
socket_close($conn);
}
运行:
sudo php server.php
因为要使用80端口,必须使用root身份运行,运行成功后,打开浏览器,输入http://127.0.0.1
,回车看到结果
Socket函数介绍
socket_create
函数原型: resource socket_create ( int $domain , int $type , int $protocol )
- domain:AF_INET、AF_INET6、AF_UNIX,
AF
的释义就address family
,地址族的意思 - type: SOCK_STREAM、SOCK_DGRAM等,最常用的就是
SOCK_STREAM
,基于字节流的SOCKET类型,也是TCP协议使用的类型 - protocol: SOL_TCP、SOL_UDP
socket_bind
函数原型: bool socket_bind ( resource $socket , string $address [, int $port = 0 ] )
- socket: 使用
socket_create
创建的socket资源 - address: ip地址
- port: 监听的端口号,WEB服务器通常为80端口
socket_listen
函数原型: bool socket_listen ( resource $socket [, int $backlog = 0 ] )
- socket: 使用
socket_create
创建的socket资源 - backlog: 等待处理连接队列的最大长度
stream_socket_server
由于创建一个SOCKET的流程总是 socket、bind、listen,所以PHP提供了一个非常方便的函数一次性创建、绑定端口、监听端口
函数原型: resource stream_socket_server ( string $local_socket [, int &$errno [, string &$errstr [, int $flags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN [, resource $context ]]]] )
- local_socket: 协议名://地址:端口号
- errno: 错误码
- errstr: 错误信息
- flags: 只使用该函数的部分功能
- context: 使用
stream_context_create
函数创建的资源流上下文
有了这个函数之后,上面的代码可以改写成:
// server.php
<?php
$sock = stream_socket_server("tcp://127.0.0.1:80", $errno, $errstr);
for ( ; ; ) {
$conn = stream_socket_accept($sock);
$write_buffer = "HTTP/1.0 200 OK\r\nServer: my_server\r\nContent-Type: text/html; charset=utf-8\r\n\r\nhello!world";
fwrite($conn, $write_buffer);
fclose($conn);
}
需要注意的是,这里不能使用socket_accept
,因为stream_socket_server
和socket_create
创建的不是同一种资源,stream_socket_server
创建的是stream
资源,这也是为什么可以用fwrite
、fread
、fclose
操作该资源的原因. 而socket_create
创建的是socket
资源,而不是stream
资源,所以socket_create
创建的资源只能用socket_write
、socket_read
、socket_close
来操作.
socket_accept
函数原型: resource socket_accept ( resource $socket )
- socket: 使用
socket_create
创建的socket资源
stream_socket_accept
函数原型: resource stream_socket_accept ( resource $server_socket [, float $timeout = ini_get("default_socket_timeout") [, string &$peername ]] )
- server_socket: 使用
stream_socket_server
创建的stream资源 - timeout: 超时时间
- peername: 设置客户端主机名称
socket_write
函数原型: int socket_write ( resource $socket , string $buffer [, int $length ] )
- socket: 调用
socket_accept
接受的新连接产生的socket
资源 - buffer: 写入到
socket
资源中的数据 - length: 控制写入到
socket
资源中的buffer
的长度,如果长度大于buffer
的容量,则取buffer
的容量
socket_close
函数原型: void socket_close ( resource $socket )
- socket:
socket_accept
或者socket_create
产生的资源,不能用于stream
资源的关闭
这章我们介绍了一些最常用的socket
相关函数,值得注意的是stream_socket_server
和socket_create
创建的资源不是同一种类型,针对这些资源的函数不能混用
最后
想要学习PHPSocket编程,点击教程【PHP Socket编程】即可,该教程共6个实验:
- TCP协议介绍
- Socket编程
- 多进程编程
- IO复用
- 进程间通信及守护进程
综合练习