3

我正在尝试创建一个 PHP 客户端来连接到一个简单的 java 服务器,发送一些数据,然后接收响应。java 服务器在与用 Java 编码的简单客户端交互时响应良好,但是一旦从 PHP 客户端发送请求,它会在调用 socket_read() 时无限期挂起。如果注释掉这一行,数据就可以正常到达,但是当它没有时,Java 服务器似乎根本没有接收到数据。这与之前提出的问题非常相似:Simple Java TCP Server and PHP Client Problems,但据我所知,我的代码在操作上与给出的解决方案几乎相同。

Java 服务器是多线程的,即用于程序的其他部分,我不相信这是导致问题的原因。php 脚本有一个用于测试的 UI。有谁知道发生了什么?

Java 服务器:

    import java.io.*;
    import java.net.*;
    import java.lang.*;

    class TCPRelayServer
    {
        String clientSentence;
        String responseString;
        ServerSocket socket;
        Socket connection;

       public void TCPRelayServer() throws Exception{
             System.out.println("Created Relay");
        }

        public void run() throws Exception{            
                clientSentence = "";
                responseString = "";
                // Open socket to all localhost connections on port
                socket = new ServerSocket(9090, 100, InetAddress.getByName(null));
                socket.setSoTimeout(5000);

             while(true)
             {
                try{
                    System.out.println("**Relay Server**  Relay Server Waiting");

                    // Setup buffers and connection
                    connection = socket.accept();
                    InputStreamReader inputStream = new InputStreamReader(connection.getInputStream());
                    BufferedReader input = new BufferedReader(inputStream);
                    DataOutputStream response = new DataOutputStream(connection.getOutputStream());

                    // Get server input
                    clientSentence = input.readLine();
                    System.out.println("**Relay Server**  Received: " + clientSentence);

                    // Perform logic
                    responseString = clientSentence.toUpperCase() + "\n";

                    // send response
                    response.writeBytes("IT WORKED!\n");
                    response.flush();
                    response.close();

                }
                catch(Exception e){
                    continue;
                }
             }
        }
    }

    class Relay implements Runnable {

        Thread runner;
        public Relay() {
        }
        public Relay(String threadName) {
            runner = new Thread(this, threadName); // (1) Create a new thread.
            System.out.println(runner.getName());
            runner.start(); // (2) Start the thread.
        }
        public void run(){
            //Display info about this particular thread
            System.out.println("Thread Started: " + Thread.currentThread());

            TCPRelayServer relay = new TCPRelayServer();
            try{
                relay.run();
            }
            catch(Exception e){
                System.out.println("Relay Server Failed to Run");
                return;
            }
        }
    }

    public class Triplestore {

        public static void main(String[] args) {
            Relay RELAY = new Relay("Relay");
            //Server SERVER = new Server("Server");
            //Client CLIENT = new Client("Client");

            //Display info about the main thread
            System.out.println("Main Thread: " + Thread.currentThread());

            while(true){

            }
        }
    }

PHP客户端:

<html>
    <head>
    <style type="text/css">

    input, textarea, label, div, a, form {
        display:inline;
        float:left;
        clear:left;
    }
    #messageLabel{
        clear:left;
        margin-top:20px;
    }
    form{
        width:600px;
    }
    textarea, input{
        font-size:14px;
        margin-left:30px;
    }
    input{
        padding:3px;
    }
    textarea{
        width:500px;
        height:300px;
        padding:10px;
    }
    input[type=submit]{
        float:right;
        margin-right: 70px;
        margin-top: 10px;
    }
    #results{
        font-family: monospace;
        clear: none;
        padding: 20px;
        background-color: black;
        color: white;
        margin-top: 30px;
        height: 299px;
        width: 500px;
        border: 3px solid #CCC;
        overflow:auto;
    }
    #results .success{color:#3ba13d;}
    #results .error{color:#c2291a;}


    </style>


    </head>
    <body>
        <form action="/test/tcp/tcp.php" method="post">
            <label for="port">Port Number: </label>
            <input type="text" name="port" id="port" value="9090"><br>

            <label for="message" id="messageLabel">Message: </label>
            <textarea placeholder="Type Message Here" id="message" name="message"></textarea><br>
            <input type="submit">
        </form>

        <div id="results">     
        <?php
            if(isset($_POST['port']) && isset($_POST['message'])){

                // Get port by service name or by port number
                $port = $_POST['port']; //getservbyname('www', 'tcp');

                // Get the IP address for the target hostname or by ip. 
                $address = '127.0.0.1'; //gethostbyname('localhost');

                // Get user message
                $message = $_POST['message'];
                $output = '';
                $next = '';


                // Create a TCP/IP socket.
                echo "Creating TCP/IP socket...";
                $socket = @socket_create(AF_INET, SOCK_STREAM, getprotobyname('tcp'));
                //SOL_TCP
                if ($socket === false) {
                    echo "<br>&nbsp;&nbsp;&nbsp;<span class='error'><br>&nbsp;&nbsp;&nbsp; FAILED Reason: socket_create() - " . socket_strerror(socket_last_error()) . "<br></span>";
                } else {
                    echo "<br>&nbsp;&nbsp;&nbsp;<span class='success'>OK</span><br>";
                }

                // Connect to address on port
                echo "Connecting to '$address' on port '$service_port'...";
                $connect = @socket_connect($socket, $address, $port);
                if ($connect === false) {
                    echo "<br>&nbsp;&nbsp;&nbsp;<span class='error'>FAILED <br>&nbsp;&nbsp;&nbsp;Reason: socket_connect() - " . socket_strerror(socket_last_error($socket)) . "<br></span>";
                } else {
                    echo "<br>&nbsp;&nbsp;&nbsp;<span class='success'>OK</span><br>";
                }


                // Send Message
                echo "Sending message...";
                $sent = @socket_sendto($socket, $message, strlen($message), MSG_EOF, $address, $port);
                if ($sent === false) {
                    echo "<br>&nbsp;&nbsp;&nbsp;<span class='error'>FAILED<br>&nbsp;&nbsp;&nbsp;Reason: socket_write() - " . socket_strerror(socket_last_error($socket)) . "<br></span>";
                } else {
                    echo "<br>&nbsp;&nbsp;&nbsp;<span class='success'>OK</span><br>";
                }

                // Read Response
                echo "Reading response...<br>";

                //$line = socket_read($socket, 1024, PHP_NORMAL_READ);
                //$output .= $line;


                while($next = socket_read($socket, 4096, PHP_NORMAL_READ)){
                    $output .= $str;
                    if($next == "" || strpos($output,"\n") !== false)
                        break;
                }

                echo 'Output: ' . $output;
                if ($output === false) {
                    echo "<br>&nbsp;&nbsp;&nbsp;<span class='error'>FAILED <br>&nbsp;&nbsp;&nbsp;Reason: socket_read() - " . socket_strerror(socket_last_error($socket)) . "<br></span>";
                } else {
                    echo "&nbsp;&nbsp;&nbsp;" . $output . "<br>";
                }

                // Close Socket
                echo "Closing socket...";
                socket_close($socket);
                echo "<br>&nbsp;&nbsp;&nbsp;<span class='success'>OK</span><br>";
            }
            else{
                echo "Please enter a port number and message.<br>";
            }
        ?>
        </div>
    </body>

</html>
4

1 回答 1

3

您在 java 中使用 readline() ,它会阻塞直到找到新行。我不认为你曾经在你的 php 代码中发送一个以新行结尾的字符串。因此,您的 java 和 php 代码都应该无限期地阻塞。

于 2012-07-15T03:35:29.457 回答