PHP里的socket_recv方法解释

以前一直经为PHP里没有低级的socket帧接收函数,看来是没看仔细,不过那些说明也太少了,(更令人气的里在英文版说明里的例子下有一句话:这个程序不能运行,因为没用listen函数,但在中文版里却没了,这个翻译的人也忒不负责了吧)

int socket_recv ( resource socket, string &buf, int len, int flags )

resource socket 是生成的套接字
string &buf 是接收缓冲区
int len 是你打算接收的长度
int flags 是一个标志
0x1 数据应该带外发送,所谓带外数据就是TCP紧急数据
0x2 使有用的数据复制到缓冲区内,但并不从系统缓冲区内删除。
0x4 不要将包路由出去。
以上三项与sock.h文件中定义完全相同
0x8 数据完整记录
0x100 数据完整处理

当socket_read在PHP_BINARY_READ模式时(默认值,但一般用PHP_NORMAL_READ )与socket_recv基本相同

下面是两个测试成的小例子
发送接收方法:
>> CODE

/*    server sock_accept
* client => filename
* server <= filesize(filename)
* client => "OK"
* server <= file_get_contents(filename)
* client => "FIN"
*    server sock_close
*
* 注意:这里用flags为0x2不清缓冲区将接收到所以读到的数据
*/


server.php

>> CODE
<?php
/*    server sock_accept
* client => filename
* server <= filesize(filename)
* client => "OK"
* server <= file_get_contents(filename)
* client => "FIN"
*    server sock_close
*
* Read buffer save all data that it have recived ever.
*/
$flag = 0x2;
error_reporting(E_ALL);

/* Allow the script to hang around waiting for connections. */
set_time_limit(0);

/* Turn on implicit output flushing so we see what we're getting
* as it comes in. */
ob_implicit_flush();

$address = '127.0.0.1';
$port = 10000;

if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) < 0) {
echo "socket_create() failed: reason: " . socket_strerror($sock) . "
";
exit;
}

if (($ret = socket_bind($sock, $address, $port)) < 0) {
echo "socket_bind() failed: reason: " . socket_strerror($ret) . "
";
exit;
}

if (($ret = socket_listen($sock, 5)) < 0) {
echo "socket_listen() failed: reason: " . socket_strerror($ret) . "
";
exit;
}

do {
if (($msgsock = socket_accept($sock)) < 0) {
echo "socket_accept() failed: reason: " . socket_strerror($msgsock) . "
";
break;
}else
{
echo "accept 
";
}

do {
$p = 0;
if (($ret = socket_recv($msgsock, $buf, 1024, $flag)) ==0 ) {
echo "$buf socket_read() failed reason: " . socket_strerror($ret) . "
";
break;    // 2;
}
$msg = substr($buf,$p); $p += strlen($msg);
echo "R:$msg
";

if(file_exists($msg))
{
$fcon = file_get_contents($msg);
$flen = filesize($msg);
if ( ( $ret = socket_write($msgsock,$flen,strlen($flen))) != strlen($flen))
{
echo "Write Error $ret
";
break;    // 2;
}
echo "S:$flen
";
if (($ret = socket_recv($msgsock, $buf, 1024, $flag)) ==0 ) {
echo "$buf socket_read() failed reason: " . socket_strerror($ret) . "
";
break;    // 2;
}
$msg = substr($buf,$p); $p += strlen($msg);
echo "R:$msg
";
$sndlen = 0;
do
{
$sndlen += socket_write($msgsock,$fcon,$flen-$sndlen);
echo "------[".$sndlen."][$flen]
";
}while($sndlen<$flen);    
echo "S:!!!!!
";

do
{
socket_recv($msgsock,$buf,1024,$flag);
if(substr($buf,-3) == "FIN")
{
echo "FIN
";
break 2;
}
}while(true);
}else
{
socket_write($msgsock,"NOFO",4);
echo "File not found
";
break;
}
} while (true);
socket_close($msgsock);
} while (true);

socket_close($sock);
?>


client.php

>> CODE
<?php
//error_reporting(E_ALL);
$flag = 0x2;
echo "TCP/IP Connection: ";

/* Get the port for the WWW service. */
$service_port = 10000;    //getservbyname('www', 'tcp');

/* Get the IP address for the target host. */
$address = '127.0.0.1';    //gethostbyname('www.example.com');

/* Create a TCP/IP socket. */
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket < 0) {
echo "socket_create() failed: reason: " . socket_strerror($socket) . "
";
exit;
} else {
echo "OK.
";
}

echo "Attempting to connect to '$address' on port '$service_port'...";
$result = socket_connect($socket, $address, $service_port);
if ($result < 0) {
echo "socket_connect() failed.
Reason: ($result) " . socket_strerror($result) . "
";
exit;
} else {
echo "OK.
";
}

$in = "server.php";
echo "S:getfile $in.";
if(socket_write($socket, $in, strlen($in))==0)
{
echo " Err
";
return;
}
echo " OK
";

if(($ret = socket_recv($socket,$out, 2048,$flag)) == 0) {
echo "Error read[".$out."]
";
}
echo "<=:$out
";
if($out !== "NOFO")
{
echo "=>:OK...";
if(socket_write($socket,"OK",2)==0 )
{
echo " Err
";
return;
}
echo " OK
";

$len = strlen($out)+ $out;
$l = 0;
while($len > $l)
{

socket_recv($socket,$t,$len,$flag);
$l= strlen($t);
echo "----[$l][$len]
";
}
echo "<====:
[".substr($t,strlen($out))."]
";

echo "=>:OK...";
if(socket_write($socket,"FIN",3)==0 )
{
echo " Err
";
return;
}
echo " OK
";
}else
{
echo "FILE not FOUND on SERVER
";
}
//socket_close($socket);
sleep(2);
echo "OK.

";
?>
原文地址:https://www.cnblogs.com/hgj123/p/4505126.html