У меня есть сокет, прослушивающий определенный порт в PHP, и я пытаюсь отправить строку, используя сокет в Java, но продолжаю получать следующую ошибку:
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
Без дополнительного описания трудно понять, в чем проблема.
Мой класс PHP выглядит следующим образом:
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);
}
}
И мой класс сокетов Java выглядит следующим образом:
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);
}
}
Что я делаю неправильно?
Я считаю, что проблема в том, что вы пытаетесь читать с вашего сокета сервера на стороне PHP, а не с вашего клиентского сокета:
socket_recv($socket, $clientMessage, 2045, MSG_WAITALL)
Это должно быть
socket_recv($client, $clientMessage, 2045, MSG_WAITALL)
Я понял проблему.
Были две проблемы, я читал из неправильного сокета, поэтому я внес изменения, как предложено @RealSkeptic, изменив их с:
socket_recv($socket, $clientMessage, 2045, MSG_WAITALL)
к
socket_recv($client, $clientMessage, 2045, MSG_WAITALL)
И еще одной проблемой был внутренний цикл while, который я использовал, который заключал в себе socket_read.
Я сделал это таким образом, потому что я получил этот код из учебника, который я нашел для server_sockets в PHP.
Но это создало проблему здесь из-за потока коммуникации:
Ответ:
На стороне Java я отправлял только один единственный ответ, тогда как на стороне PHP я использовал socket_read «бесконечно» в цикле while, пока не получил строку «close». Это создавало проблему, потому что после получения первого ответа читать больше нечего. Таким образом, ошибка.
Поэтому, чтобы решить проблему, мне просто пришлось удалить цикл while (и я удалил socket_write, так как для моих целей мне не нужно отправлять какую-либо информацию).
Рабочий пример для класса 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);
}
}