Search code examples
javaphpsocketsserversocket

Sending message from a Java socket to a PHP server socket


I have a socket listening to a certain port in PHP, and I am trying to send a string using a socket in Java, but I keep getting the following error:

Warning: socket_recv(): unable to read from socket [0]: The operation completed successfully.
 in H:\Dropbox\EISTI\www\java-instagram-web\src\Client\Component\Server\Client.php on line 55

Without any more description, it is hard to understand what is the problem.

My PHP class looks like the following:

class Client {
    private $address;
    private $port;
    private $command;

    public function __construct($port, $address, $addressServer, $portServer, $command)
    {
        set_time_limit(0);
        $this->address = $address;
        $this->port = $port;
        $this->init();
    }

    private function init(){

        //Create socket
        if (! $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) {
            $this->showError('socket create');
        }
        echo "Server Created\n";

        //Bind socket
        if (!socket_bind($socket, $this->address, $this->port)) {
            $this->showError('socket bind');
        }
        echo "Server bind to $this->address and $this->port \n";

        if (!socket_listen($socket)) {
            $this->showError('socket listen');
        }
        echo "Server Listening \n";

        do {
            $client = socket_accept($socket);
            echo "connection established\n";

            $message = "\n Hey! welcome to the server\n";
            socket_write($client, $message, strlen($message));

            do {
                if (! socket_recv($socket, $clientMessage, 2045, MSG_WAITALL)) {
                    $this->showError('socket receive');
                }
                $message = "Command Received\n";
                echo $clientMessage;

                socket_send($client, $message, strlen($message), 0);

                if (!$clientMessage = trim($clientMessage)) {
                    continue;
                }

                if (trim($clientMessage) == 'close') {
                    socket_close($client);
                    echo "\n\n--------------------------------------------\n".
                        "ClientRequest terminated\n";
                    break 1;
                }
            } while(true);

        } while(true);
    }

    private function showError($message) {
        echo ("Error: ".$message);
        exit(666);
    }
}

And my Java socket class looks like the following:

public class ResponseToClient {
    private String host;
    private int port;
    private Socket socket;
    private PrintStream theOut;
    private String resultLocation;

    /**
     * Constructor
     */
    public ResponseToClient(String path) {
        this.host = "localhost";
        this.port = 1000;
        this.resultLocation = path;
    }

    /**
     * Setting up Socket
     */
    public void init(){
        try{

            socket = new Socket(host, port);
            theOut = new PrintStream(socket.getOutputStream());

            //Send Command
            sendCommand();

            //Closing connections
            socket.close();
            theOut.close();

        }
        catch (IOException e){
            e.printStackTrace();
        }
    }

    /**
     * Send Command
     */
    public void sendCommand()
    {
        theOut.println(Messages.type_response + Messages.seperator_client + resultLocation);
        System.out.println(Messages.type_response + Messages.seperator_client + resultLocation);
    }
}

What am I doing wrong?


Solution

  • I figured out the problem.

    There were two problems, I was reading from the wrong socket, So i made the change as suggested by @RealSkeptic, changing from :

    socket_recv($socket, $clientMessage, 2045, MSG_WAITALL)
    

    To

    socket_recv($client, $clientMessage, 2045, MSG_WAITALL)
    

    And Another Problem was the inner while loop that I was using was which was en-globing the socket_read.

    I did it this way, because I had got this code off a tutorial I found for server_sockets in PHP.

    But it created a problem here because of the flow of the communication:

    Answer:

    On the Java side I was sending only one single response, whereas on the PHP side I was using socket_read "infinitely" in the while loop until I received the string "close". This was creating the problem because, after receiving the first response, there is nothing else to read. Thus the error.

    So to solve the problem I just had to remove the while loop, (and I removed the socket_write as for my purpose I do not need to send any information).

    The working example for the class Client:

    class Client {
    
        private $addressServer;
        private $portServer;
        private $address;
        private $port;
        private $command;
    
        public function __construct($port, $address, $addressServer, $portServer, $command)
        {
            set_time_limit(0);
            $this->addressServer = $addressServer;
            $this->address = $address;
            $this->portServer = $portServer;
            $this->port = $port;
            $this->command = $command;
            $this->init();
        }
    
        private function init() {
    
            //Send request to the Java server
            $request = new Request(
                $this->addressServer, $this->portServer, $this->command
            );
    
            //create socket
            if (! $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) {
                $this->showError('socket create');
            }
            echo "Server Created\n";
    
            //Bind socket
            if (!socket_bind($socket, $this->address, $this->port)) {
                $this->showError('socket bind');
            }
            echo "Server bind to $this->address and $this->port \n";
    
            if (!socket_listen($socket)) {
                $this->showError('socket listen');
            }
            echo "Server Listening \n";
    
            do {
                $client = socket_accept($socket);
                echo "connection established\n";
    
                if(!$clientMessage = socket_read($client, 10000, PHP_NORMAL_READ)){
                    $this->showError('socket read');
                }
    
                echo "Command Received\n";
                echo $clientMessage;
    
            } while(true);
        }
    
        private function showError($message){
            echo ("Error: ".$message);
            exit(666);
        }
    }