【问题标题】:PHP socket_read() and socket_recv() WoesPHP socket_read() 和 socket_recv() 问题
【发布时间】:2013-07-26 22:09:27
【问题描述】:

编辑:我已经解决了自己的问题并修复了以下代码以反映这些更改,以防万一有人遇到同样的困难。此代码适用于 PHP 客户端和 Java 服务器连接。

我知道论坛上充斥着这些问题......但是,我已经尝试了几乎所有其他方法超过 8 小时,但我已经无计可施了。我正在尝试将字符串从 java Socket 发送到 PHP Socket。我是一个 PHP 套接字新手,所以希望有人可以很容易地诊断出我的问题......这是 PHP 代码:

<html>

<head>
</head>

<body>
<?php
//connection to NetworkService in app to manage incoming request
$addr = 'your server address';
$port = 1740;

$socket = socket_create(AF_INET, SOCK_STREAM, getprotobyname('tcp'));
socket_connect($socket, $addr, $port);

//"\r\n" is very important as it signifies to the server
// that this is the end of the transmission 
$request = "message to send \r\n";

//no flags needed circa php 5.2
$sent = socket_sendto($socket, $request, strlen($request), 0 , $addr, $port);

if($sent !== FALSE){
    $message = '';
    $next = ''; 

    //loop through to continue appending until everything has been read
    while($next = socket_read($socket, 4096)){
        $message .= $next;
    }
    echo $message;
} else{
    echo "Failed.";
}

socket_close($socket);
?>
</body>

</html>

Java 代码:

public class TestServer{
    public static void main(String argv[0]) throws Exception{
        String in; String out = "Hello PHP\r\n";
        ServerSocket inSock = new ServerSocket(1740);

        while(true){
            System.out.println("Now accepting connections");
            Socket outSock = inSock.accept();
            BufferedReader bReader = new BufferedReader(
                 new InputStreamReader(outSock.getInputStream()));
            PrintWriter sender = new PrintWriter(outSock.getOutputStream());
            in = bReader.readLine();
            System.out.println("Received: " + in);
            dWriter.print(out);
            System.out.println("Sent: " + out);
        }
    }
}

问题不在于第一次发送(从 PHP 到 JAVA),而在于第二次发送(响应)只是挂起。 Java 代码完全运行,所以我知道问题与 socket_read() 或 socket_recv() 函数有关。我尝试过 sleep() 并尝试使用 socket_setnoblock() 的方法(尽管可能不正确)。正如您在我的“OPTION:”cmets 中看到的那样,我在这里也尝试了几种不同的方法,但都无济于事。我能错过什么?提前非常感谢您!

【问题讨论】:

    标签: java php sockets networking


    【解决方案1】:

    根据the manualsocket_recv()会返回一个整数,即接收到的字节数。

    问题是false !==,你不应该在这里使用它(因为socket_recv() 返回一个整数)。这个条件应该够了:

    while(0 != socket_recv($socket, $out, 1024)){
          if($out != null)
            $fullResult .= $out;
        };
    

    socket_last_error()可能对您感兴趣。

    【讨论】:

    • 感谢第二双眼睛!我修复了那部分,但仍然有同样的问题。更新后的代码已编辑到原帖中。
    • 使用 socket_last_error() 是一个很好的技巧。但是,由于脚本现在挂在 socket_recv() 行(我认为),因此永远不会调用 socket_last_error() 方法...
    【解决方案2】:

    有点晚了(遇到这个正在寻找另一个问题。

    在您的 PHP 中,尝试将套接字设置为非阻塞,然后循环,直到获得所需的“消息结束”响应(强制 Java 发送,以防下面是换行符)。你也可以使用 socket_read (因为它以换行符结尾)但是如果我在下面使用的代码如下。

    socket_set_nonblock ($socket);
    $receiveStartTime = microtime(true);
    $response = '';
    $retval = false;
    while(microtime(true) - $receiveStartTime < 0.5) {
        $n = @socket_recv($socket, $dataIn, 1024, 0);  // Assume max return value is 1024 bytes.
        if ($n) {
            $response .= $dataIn;
        }
        if (strpos($dataIn, "\n") !== false) {
            @socket_clear_error ( $socket );
            $response = str_replace("\n", '', $response);
            break;
        }
    }
    if (socket_last_error($socket) > 0) {
        $this->lastErrorNum = socket_last_error($socket);
        $this->lastErrorMsg = 'Unable to read from socket: ' . socket_strerror($this->lastErrorNum);
        @socket_clear_error ( $socket );
    } else {
        $retval = $response;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-21
      • 2012-02-04
      • 1970-01-01
      • 2023-03-30
      • 2015-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多