PHP fsockopen()失败不会打开端口,但telnet可以工作

时间:2018-09-29 07:17:50

标签: php sockets serial-port

在尝试解决最近两天的网络问题时,我遇到了一个奇怪的问题。我无法在php网页上打开端口25003。该代码似乎没有问题,但是,如下所示。

$host = 'xx.xx.xx.xx';    // statis public ip address assigned by my isp
$ports = array(80, 25003);

foreach ($ports as $port)
{
    $connection = fsockopen($host, $port);

    if (is_resource($connection))
    {
        echo '<h2>' . $host . ':' . $port . ' ' . '(' . getservbyport($port, 'tcp') . ') is open.</h2>' . "\n";

        fclose($connection);
    }

    else
    {
        echo '<h2>' . $host . ':' . $port . ' is not responding.</h2>' . "\n";
    }
}

端口80显示为打开状态,但未显示端口25003。

该站点也使用静态IP托管在Bluehost共享托管计划中。与它们进行交叉验证超过3次,即入站和出站连接上的端口25003均处于打开状态。他们会撒谎吗,我不这么认为。

在客户端PC上的设置:

(1) Firewall is disabled for testing purpose.

(2) Port forwarding is done correctly in router. I assume so because
 I can easily telnet MY PUBLIC IP with a port 25003 within the same
 LAN and from phone using sim card's internet.

(3) I did a port check from https://ping.eu/port-chk/ and it shows open.

(4) Client PC has a serproxy installed for serial to IP & Port.
(5) When I do a port check from above link, serproxy shows following message which seems to be okay on its part.
      * server thread launched
      * server(1) - thread started
      * server(1) - EOF from sock
      * server(1) - Exiting

(6) Again, when I telnet from external lan, it shows above message in Client PC's Serproxy which means it is doing its work properly. And it shows correct data from serial port to cmd line while telneting. 

问题是当我使用上述代码fsockopen时,它说CONNECTION REFUSED。

下面是我的实际代码,应尝试从串行端口连接并读取数据,但连接被拒绝。

$fp = fsockopen("tcp://xx.xx.xx.xx", 25003, $errno, $errstr);
if (!$fp) {
    echo "$errstr ($errno)<br />\n";
} else {
    if (!feof($fp)) {
        $weight = trim(fgets($fp, 64)," ");
    }
}
echo $weight;
 fclose($fp);

我认为问题出在bluehost共享服务器或客户端Windows PC或SERPROXY或本地网络配置中。恐怕在设置正确的SERPROXY中,除了波特率,COM端口等以外,可能还有其他主要配置更改。

我现在对如何解决上述问题一无所知。如果有人可以帮助将不胜感激。

如果有人要检查连接性,我将共享公共IP。

1 个答案:

答案 0 :(得分:1)

就像我提到的那样-以前,当我尝试连接所有尝试均失败时,但下面的两种方法现在都可以使用,因此我认为问题已解决。我可能建议重启网络服务器和浏览器

<?php
    set_time_limit( 0 );
    error_reporting( E_ALL );

    $address = 'xxx.xxx.xxx.xxx';
    $port = 25003;


    /* Method #1 */
    $fp = fsockopen( "tcp://{$address}", 25003, $errno, $errstr );
    if( !$fp ) echo "$errstr ($errno)<br />\n";
    else {
        if( !feof( $fp ) ) {
            $weight = trim(fgets($fp, 64)," ");
        }
    }
    printf('<h1>Method #1</h1>Weight: %s<br /><br />',$weight);
    fclose($fp);




    /* Method #2 */
    function geterror(){
        $obj=new stdClass;
        $obj->code=socket_last_error();
        $obj->error=socket_strerror( $obj->code );
        return $obj;
    }
    function negotiate( $socket ) {
        socket_recv( $socket, $buffer, 1024, 0 );

        for( $chr = 0; $chr < strlen( $buffer ); $chr++ ) {
            if( $buffer[ $chr ] == chr( 255 ) ) {
                $send = ( isset( $send ) ? $send . $buffer[$chr] : $buffer[$chr] );

                $chr++;
                if( in_array($buffer[$chr], array(chr(251), chr(252))) ) $send .= chr(254);
                if( in_array($buffer[$chr], array(chr(253), chr(254))) ) $send .= chr(252);

                $chr++;
                $send .= $buffer[$chr];
            } else {
                break;
            }
        }
        if( isset($send)) socket_send($socket, $send, strlen($send), 0);
        if( $chr - 1 < strlen($buffer)) return substr($buffer, $chr);
    }



    $socket = socket_create( AF_INET, SOCK_STREAM, SOL_TCP );


    try{

        if( $socket && is_resource( $socket ) ){
            if( !socket_connect( $socket, $address, $port ) ){
                $err=geterror();
                throw new Exception( sprintf( 'socket_connect: %s', $err->error ), $err->code );
            } else {

                while( true ){

                    $e=null;
                    $w=null;
                    $r = array( $socket );
                    $c = socket_select( $r, $w, $e, 5 );

                    foreach( $r as $read_socket ) {
                        if( $r = negotiate( $read_socket ) ) {
                            exit( sprintf( '<h1>Method #2</h1>Reading: %s', print_r( $r, true ) ) );
                        }
                    }
                }
            }

        } else {
            $err=geterror();
            throw new Exception( sprintf( 'Failed to create socket: %s',$err->error ), $err->code );
        }

    }catch( Exception $e ){
        printf( "
        <pre>
            <h1>Error: %d</h1>\nMessage: %s\nTrace: %s\nLine: %d
        </pre>",$e->getCode(),$e->getMessage(),$e->getTraceAsString(),$e->getLine() );
    }
    socket_close( $socket );
?>

output from the two methods shown

相关问题