标签:文件 基础知识 链接 accept post text recv 读取数据 pen
fopen
等操作,其实就是用的流,fopen(‘abc.txt‘)
实际上就是fopen(‘file://abc.txt‘)
,或者是与app交互用到的php://input
等获取post数据也是流的一种服务端函数
stream_socket_server
( string $local_socket [, int &$errno [, string &$errstr [, int $flags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN [, resource $context ]]]] ) : resource
socket_create
、socket_bind
、socket_listen
这三个函数,例如:$socket = stream_socket_server(‘tcp://0.0.0.0:8000‘);
相当于$socket = socket_create(AF_INET, SOCK_STREAM, 0);
+socket_bind($socket, ‘0.0.0.0‘, 8000);
+socket_listen($socket);
STREAM_SERVER_LISTEN
是不需要的,$context则是上下文,后面有单独的函数来生成此类型,还有需要注意的是,stream_socket_server
和socket_create
的返回值虽然都是resource,但两个不能通用,socket扩展中有单独的函数来转换这两者。stream_socket_accept
( resource $server_socket [, float $timeout = ini_get("default_socket_timeout") [, string &$peername ]] ) : resource
socket_accept
,需要注意的是第一个参数,只能是stream_socket_server
的返回值。客户端函数
stream_socket_client
( string $remote_socket [, int &$errno [, string &$errstr [, float $timeout = ini_get("default_socket_timeout") [, int $flags = STREAM_CLIENT_CONNECT [, resource $context ]]]]] ) : resource
socket_create
、socket_connect
这两个函数,例如$socket = stream_socket_client(‘tcp://0.0.0.0:8000‘‘)
相当于$socket = socket_create(AF_INET, SOCK_STREAM, 0);
+$result = socket_connect($socket, ‘0.0.0.0‘, 8000);
STREAM_CLIENT_CONNECT
和STREAM_CLIENT_ASYNC_CONNECT
,第二个参数是设置异步,与阻塞又不太相同,挺让人费解的,而且网上也基本搜不到相关资料,当设置此参数时,将不会检测地址端口是否真的能连通,都为立即返回正常的资源resource,那如何来确定服务端是否真的能链接上呢?目前个人所知的方式是用stream_select
类似的多路IO复用来检测,当真正链接或链接失败后内核会通知到read或者write或者except(具体通知到哪个windows和linux不一致,需要区别处理),下面的stream_select
函数和后期IO多路复用时会讲到。读写函数
fread
( resource $handle , int $length ) : string
fwrite
( resource $handle , string $string [, int $length ] ) : int
stream_socket_recvfrom
( resource $socket , int $length [, int $flags = 0 [, string &$address ]] ) : string
stream_socket_sendto
( resource $socket , string $data [, int $flags = 0 [, string $address ]] ) : int
fread
和fwrite
基本一致,但功能更多一些,$flags参数可以设置发送OOB数据,而$address参数则多是用于udp通信,由于udp通信时不使用stream_socket_accept
,所以无法获取到新的resource,那就无法向指定的客户端中写数据,所以一般先用stream_socket_recvfrom
获取最后引用参数$address即为客户端的地址,然后再用stream_socket_sendto
设置$address,来向指定的客户端发送。其它常用函数
stream_select
( array &$read , array &$write , array &$except , int $tv_sec [, int $tv_usec = 0 ] ) : int
socket_select
,详细的在后面的IO模型中会总结stream_set_blocking
( resource $stream , bool $mode ) : bool
socket_set_block
和socket_set_nonblock
,但是还是有些区别的,上节我们知道socket的阻塞影响的函数为:socket_connect、socket_accept以及各种socket读写函数,而stream的阻塞影响的函数仅仅为stream相关的读写函数,stream_socket_accept
不受影响,一直是阻塞,stream_socket_client
更不会受影响,因为stream_socket_client
的返回值,才能作为stream_set_blocking
的第一个参数,所以上方说stream_socket_client
的参数flags设置为异步,算是弥补了这一问题。fclose
( resource $handle ) : bool
stream_socket_shutdown
( resource $stream , int $how ) : bool
stream_socket_shutdown
还可以控制只关闭读或者只关闭写socket_import_stream
( resource $stream ) : resource
socket_export_stream
( resource $socket ) : resource
stream_context_create
stream_socket_server
和stream_socket_client
最后一个参数就是上下文,相关的参数需要经过此函数的组装后才能传入,我们可能早就接触过,例如我们经常用到的file_get_content
可以模拟post来获取数据,就需要用到它的第三个上下文参数。$socket = stream_socket_server(‘tcp://127.0.0.1:8888‘, $errno, $errstr);
while ($conn = stream_socket_accept($socket)) {
fwrite($conn, "hello\n");
fclose($conn);
}
fclose($socket);
$socket = stream_socket_client(‘tcp://127.0.0.1:8888‘, $errorno, $errstr);
while (!feof($socket)) {
echo fread($socket, 1024);
}
fclose($socket);
php socket网络编程基础知识(三):stream函数
标签:文件 基础知识 链接 accept post text recv 读取数据 pen
原文地址:https://www.cnblogs.com/vishun/p/10475296.html