【问题标题】:PHP fsockopen() fails does not open port but telnet worksPHP fsockopen() 失败未打开端口但 telnet 工作
【发布时间】:2018-09-29 16:01:59
【问题描述】:

在过去 2 天里,我遇到了一个奇怪的网络问题,试图解决这个问题。我无法在 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。

【问题讨论】:

  • 似乎对我有用(使用上一个问题的 ip)
  • @RamRaider 任何提示,问题可能出在哪里?
  • 否 - 我之前尝试过所有连接尝试都被拒绝(无法连接等),但现在使用上述方法以及之前的尝试(socket_create、socket_connect 等)似乎没问题
  • @RamRaider 我应该假设问题出在 Bluehost 上吗?因为如果它适用于你,它也应该适用于我的,不是吗?

标签: php sockets serial-port


【解决方案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 );
?>

【讨论】:

  • 谢谢,问题出在bluehost上。当联系 bluehost 时,他们拒绝重新启动网络服务器,因为我在共享主机中。还有什么特别要问的,因为套接字不仅仅在 buehost 中工作。
  • 尝试在您的本地/开发网络服务器上运行上述代码(使用正确的 ip)...那么它对您有用吗?
  • 使用上面的 fsockopen 代码,我现在可以成功获取数据,但我想知道我是否可以在我的网页上实时获取重量闪烁,因为它在称重指示器中发生变化。可能吗 ?任何提示,我该怎么做?顺便说一句,非常感谢您的回答,这让我确信问题出在 Bluehost 上,尽管直到现在还没有解决,因为他们说他们正在努力解决。它在我的本地服务器和另一个 A2 托管站点上运行良好。
猜你喜欢
  • 2011-07-14
  • 1970-01-01
  • 2012-02-15
  • 1970-01-01
  • 1970-01-01
  • 2013-07-16
  • 2011-11-20
  • 2011-08-14
  • 2015-06-28
相关资源
最近更新 更多