zoukankan      html  css  js  c++  java
  • 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.
    
    ";
    ?>
  • 相关阅读:
    java爬虫(八)使用node.js获取network中api接口内信息并用java的jsoup重写该方法
    java爬虫(七)使用httpclient模拟浏览器GET,POST
    Java selenium对cookies的操作
    java爬虫(六)分析AJAX接口获取网页动态内容
    java爬虫(五)利用selenium 模拟点击获取动态页面的内容
    java爬虫(四)利用Jsoup获取需要登陆的网站中的内容(无验证码的登录)
    java爬虫(三)利用HttpClient和Jsoup模拟网页登陆(无验证码)
    Java远程服务器调优
    20 vue-router的使用
    19 关于Vue中main.js,App.vue,index.html之间关系进行总结
  • 原文地址:https://www.cnblogs.com/hgj123/p/4505126.html
Copyright © 2011-2022 走看看