【问题标题】:Is it possible to use a socket accepted on one PHP script on another?是否可以在另一个 PHP 脚本上使用一个接受的套接字?
【发布时间】:2013-07-25 08:38:36
【问题描述】:

我想实现一些看似荒谬的事情。

我创建了一个 PHP 脚本来创建服务器套接字。我可以从 java 客户端连接到服务器套接字。

现在我想要在服务器端的某个地方维护这个套接字,以便我以后可以在需要时访问它。

但是,这里的问题是,一旦 respond() 函数终止,socket 就关闭了,Run 类中的 br.readLine() 方法接收到空行。

出于我的目的,readLine() 方法应该继续等待响应。

到目前为止我做了什么......

regsock.php (应该在哪里注册套接字)

  <?php
    set_time_limit(0);
    $fh = fopen("reg.txt", "w");
    fwrite($fh, "SERVER Starting\r\n");
    $sersock = socket_create_listen(1234);
    fwrite($fh, "SERVER Running\r\n");

    while(true){
        respond();
    }

    function respond(){
        global $sersock, $fh;
        $sock = socket_accept($sersock);
        fwrite($fh, "Client Connected\r\n");
        echo "Client: ".socket_read($sock, 1024);
        socket_write($sock, "OK\n\r");

        //Some way to store client sockets?
    }
    socket_close($sersock);
    fclose($fh);
?>

运行.java

Socket socket = new Socket("localhost", 1234);

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
                    socket.getOutputStream()));
BufferedReader br = new BufferedReader(new InputStreamReader(
                    socket.getInputStream()));

bw.write("Server OK?");
bw.flush();
System.out.println("Server:"+br.readLine()); //Output-> Server:OK
System.out.println("Server:"+br.readLine()); //Output-> Server:
bw.close();
br.close();
socket.close();

还有,remote.php (我想访问 resgsock.php 上接受的套接字)

<?php
    $sock = //Retrieve socket resource here
    fwrite($sock, "REMOTE PAGE\r\n");
    echo "Socket write complete";
?>

有没有可能,或者我只是做错了。

这可以通过其他方法来完成吗?

【问题讨论】:

标签: java php sockets


【解决方案1】:

只有当remote.php与regsock在同一进程或子进程中执行时,regsock.php中接受的套接字才能传递给remote.php。

例如你可以这样做:

# In global setup: handle child process termination automatically
# Might break calls to "system" though
pcntl_signal(SIGCHLD, SIG_IGN);

function respond(){
    global $sersock, $fh;
    $sock = socket_accept($sersock);
    fwrite($fh, "Client Connected\r\n");
    echo "Client: ".socket_read($sock, 1024);
    socket_write($sock, "OK\n\r");

    $pid = pcntl_fork();
    if ($pid == 0) {
        # This is now a subprocess. If I "include" remote.php
        # it can operate on $sock as if it was its own.
        include "remote.php";
        # Now exit the subprocess
        exit;
    } elsif ($pid < 0) {
        # fork failed, handle error
    } else {
        echo "Subprocess running with pid $pid!";
        # Close the copy of the socket in parent process,
        # subprocess has a copy of its own.
        socket_close($sock);
    }

}

【讨论】:

  • 即使不分叉另一个进程也可以工作,因为来自 remote.php 的代码将在 response() 函数下执行。我希望从浏览器访问 remote.php。
  • 好的,那我得想办法方便沟通了……谢谢你的回复。
  • 您可以让“regsock”启动一个子进程,等待来自“远程”的连接,然后在两个套接字之间传输数据,但对于您最初尝试的问题,也许有更简单的解决方案解决。
  • @Joni:坦率地说,这是我在网络上为这个确切问题找到的唯一解决方案。感谢您在这里发表评论!只有一个警告:由于某种原因,socket_listen 每个连接只能将一条消息通过管道传递给 socket_send。
  • @Everst 在写完这个答案后,我了解到你可以使用 UNIX 域套接字中的辅助数据将打开的文件描述符从一个进程传递到另一个进程,但如果你使用像 OP 这样的 Java,它可能不会值得麻烦(Java 中没有对 UNIX 套接字的内置支持)。但是,如果您发布有关 socket_listen 问题的问题,有人可能会帮助您解决这个问题
猜你喜欢
  • 1970-01-01
  • 2023-02-11
  • 2023-02-08
  • 1970-01-01
  • 2017-02-07
  • 1970-01-01
  • 1970-01-01
  • 2010-11-29
  • 1970-01-01
相关资源
最近更新 更多