PHP -Socket kann die Serverantwort nicht lesenJava

Java-Forum
Anonymous
 PHP -Socket kann die Serverantwort nicht lesen

Post by Anonymous »

Ich verwende die Amphp -Version 2.6, um asynchrone Socket -Verbindungen zu einem Minecraft -Server zu erstellen. Während dieser Verbindung sende ich Ganzzahlen, Zeichenfolgen und Bytes an den Server, um Informationen aus einem Plugin abzurufen, das auf dem Minecraft -Server ausgeführt wird. Ganzzahl und schreibt es als Ganzzahl aus. Das auf sich gezogene Plugin markiert den Erfolg als wahres < /li>
Das Java -Plugin prüft die IP -Adresse der eingehenden Verbindung. Wenn es in der zulässigen Liste ist, schreibt es Ganzzahl 1 aus, um die Seite des Phps zu informieren, dass der Server die Verbindung akzeptiert hat. Es erfordert < /li>
Nachdem die Informationen empfangen wurden, sendet es ein Byte 3 an den Server, um die Verbindung zu schließen. Wenn das Skript die Serverantwort nicht lesen kann, wird kein weiteres Byte an das Java -Plugin gesendet, und das verursacht die EOFException. Ich bin mir ziemlich sicher.

Code: Select all

[11:31:01 INFO]: StatusMC >  Random code: 726462011
[11:31:01 INFO]: StatusMC >  119f9fcfa7e8d56002e755598950a130bbf999004445ce28e070f5d639157ac9757450bb50744e9552bde50e3a2fdc584f468351248854acc72c1c3c36ee931e
[11:31:03 INFO]: StatusMC >  Successfully connected to the server!
[11:31:03 INFO]: StatusMC >  IO exception 1: null
[11:31:03 WARN]: java.io.EOFException
[11:31:03 WARN]:        at java.base/java.io.DataInputStream.readUnsignedByte(DataInputStream.java:290)
[11:31:03 WARN]:        at java.base/java.io.DataInputStream.readByte(DataInputStream.java:268)
[11:31:03 WARN]:        at StatusMCv1.3.7-dev.jar//net.statusmc.utils.SocketServer.run(SocketServer.java:99)
< /code>
Mein Php -Code: < /p>
function asyncTask(string $server_identifier, string $monitor_id, string $page_id, string $host, string $secret_key, int $port, int $timeout, int $writeTimeout): Promise {
return call(function () use ($server_identifier, $monitor_id, $page_id, $host, $secret_key, $port, $timeout, $writeTimeout) {
$tpsCompleted = false;
try {
$cstatus = new Status();
$tpsDouble = 0;
$message = "N/A";
// Create an asynchronous socket connection using Amphp
/** @var \Amp\Socket\ClientSocket $socket */
$socket = yield timeout(Socket\connect("tcp://{$host}:{$port}"), $timeout);
//Olen lisanud järgmisele kahele reale timeouti, sest isegi kui connection ei timeouti ja connectib edukalt, siis
//on võimalik, et serverilt data kätte saamisega võib tekkida probleeme, nt on pandud Serveri port mitte StatusMC plugina port
//ja kui siin timeoute pole, siis see võib kogu scripti timeoutida ja tekib Gateway time-out
//teistel ridadel pole seda pannud, sest tõenäoliselt ta timeoutib kohe alguses
//https://chatgpt.com/c/67767b7d-a7c8-8010-a4e5-679615fbf5ca
yield timeout($socket->write(chr(1)), $writeTimeout);
$randomInt = yield timeout(readRawInt($socket), $writeTimeout);
$cstatus->log("TPS MONITOR ERROR", 'admin', 'Random int has been read. Random int: '.$randomInt.' Monitor ID: '.$monitor_id);

//Stringi writimine, secret key saatmine koos random Intiga
$message = hash("SHA512", $randomInt . $secret_key);
$stringSize = 0;
// Write the length of the hash (as an integer)
yield $socket->write(pack("N", strlen($message)));

// Write the hash itself
yield timeout($socket->write($message), $writeTimeout);
$cstatus->log("TPS MONITOR ERROR", 'admin', 'Message has been written. Message: '.$message.' Monitor ID: '.$monitor_id);
$serverResponse = yield timeout(readRawInt($socket), $writeTimeout);
$cstatus->log("TPS MONITOR ERROR", 'admin', 'Server response has been read. Server response: '.$serverResponse.' Monitor ID: '.$monitor_id);
if($serverResponse == 1) {
$cstatus->log("TPS MONITOR ERROR", 'admin', 'Server response 1. Monitor ID: '.$monitor_id);
yield timeout($socket->write(chr(2)), $writeTimeout);
$tps = yield timeout(readRawDouble($socket), $writeTimeout);
$cstatus->log("TPS MONITOR ERROR", 'admin', 'TPS double has beenr read. TPS: '.$tps.  ' Monitor ID: '.$monitor_id);

if($tps == 404500) { //This is a fail-safe, if we receive a double 404500 it means that we didn't get a correct TPS, trying again
yield timeout($socket->write(chr(2)), $writeTimeout);
$tps = yield timeout(readRawDouble($socket), $writeTimeout);
if($tps $server_identifier, //Minu enda välja mõeldud mingi pikk jada, millega verifyme, et request tuli just sellelt API-lt
'page_id' => $page_id,
'monitor_id' => $monitor_id,
'tps' => $tps,
'status' => 'invalid_data'
];
} else {
//Kogume data API-le, et saata hiljem kõikide monitoride data koos
$result = [
'server_identifier' => $server_identifier, //Minu enda välja mõeldud mingi pikk jada, millega verifyme, et request tuli just sellelt API-lt
'page_id' => $page_id,
'monitor_id' => $monitor_id,
'tps' => $tps,
'status' => 'successful'
];
}
} else { //Kui saadud TPS ei ole 404500, siis toimime tavapäraselt
if($tps $server_identifier, //Minu enda välja mõeldud mingi pikk jada, millega verifyme, et request tuli just sellelt API-lt
'page_id' => $page_id,
'monitor_id' => $monitor_id,
'tps' => $tps,
'status' => 'invalid_data'
];
} else {
//Kogume data API-le, et saata hiljem kõikide monitoride data koos
$result = [
'server_identifier' => $server_identifier, //Minu enda välja mõeldud mingi pikk jada, millega verifyme, et request tuli just sellelt API-lt
'page_id' => $page_id,
'monitor_id' => $monitor_id,
'tps' => $tps,
'status' => 'successful'
];
}
}

} else { //Kui $serverResponse pole 1 ehk ei connectinud ära, siis
$cstatus->log("TPS MONITOR ERROR", 'admin', 'Server response not 1. Monitor ID: '.$monitor_id.' Server response: '.$serverResponse);
//Kogume data API-le, et saata hiljem kõikide monitoride data koos
$result = [
'server_identifier' => $server_identifier, //Minu enda välja mõeldud mingi pikk jada, millega verifyme, et request tuli just sellelt API-lt
'page_id' => $page_id,
'monitor_id' => $monitor_id,
'tps' => 0,
'status' => 'connection_error'
];
}
yield timeout($socket->write(chr(3)), $writeTimeout);
//Annan Javale veidi aega, et closida connection
yield new \Amp\Delayed(100); // 100ms delay
$socket->close();

} catch (TimeoutException $e) {
$cstatus = new Status();
$cstatus->log("TPS MONITOR ERROR", 'admin', 'TPS Monitor timeout exception occured. Monitor ID: '.$monitor_id.' Exception: '.$e);

//Kogume data API-le, et saata hiljem kõikide monitoride data koos
$result = [
'server_identifier' => $server_identifier, //Minu enda välja mõeldud mingi pikk jada, millega verifyme, et request tuli just sellelt API-lt
'page_id' => $page_id,
'monitor_id' => $monitor_id,
'tps' => 0,
'status' => 'connection_error'
];
} catch (\Exception $e) {
$cstatus = new Status();
$cstatus->log("TPS MONITOR ERROR", 'admin', 'TPS Monitor exception occured.  Monitorid ID: '.$monitor_id.' Exception: '.$e);
if (isset($socket)) {
yield timeout($socket->write(chr(3)), $writeTimeout);
//Annan Javale veidi aega, et closida connection
yield new \Amp\Delayed(100); // 100ms delay
$socket->close();
}

//Kogume data API-le, et saata hiljem kõikide monitoride data koos
$result = [
'server_identifier' => $server_identifier, //Minu enda välja mõeldud mingi pikk jada, millega verifyme, et request tuli just sellelt API-lt
'page_id' => $page_id,
'monitor_id' => $monitor_id,
'tps' => 0,
'status' => 'connection_error'
];
}
return $result;
});
< /code>
} < /p>
// Method to read an integer from the socket's response
function readRawInt($socket): Promise {
return Amp\call(function () use ($socket) {
$buffer = '';

while (strlen($buffer) < 4) {
$chunk = yield $socket->read();
if ($chunk === null) {
throw new \Exception("Socket closed before reading 4 bytes.");
}
$buffer .= $chunk;
}

// Convert the first 4 bytes of the buffer to an integer
$intData = unpack('N', substr($buffer, 0, 4))[1];

return $intData;
});
}

function readRawDouble(ResourceSocket $socket): \Amp\Promise {
return \Amp\call(function () use ($socket) {
// Read 8 bytes from the socket
$data = yield $socket->read(8);

// Ensure we got exactly 8 bytes
if ($data === null || strlen($data) !== 8) {
throw new \RuntimeException("Expected 8 bytes for the double, got " . (strlen($data) ?: 0) . " bytes.");
}

// Reverse the data if the machine is little-endian
if (pack('L', 1) === pack('V', 1)) { // Detect little-endian
$data = strrev($data);
}

// Unpack the data as a double
$unpacked = unpack('d', $data);

// Validate the unpacked result
if ($unpacked === false || !isset($unpacked[1])) {
throw new \RuntimeException("Failed to unpack the double. Data: " . bin2hex($data));
}

echo "Raw data: " . bin2hex($data) . PHP_EOL; // Print the raw bytes read
echo "Unpacked double: " . $unpacked[1] . PHP_EOL; // Print the resulting double

return $unpacked[1]; // Return the unpacked double
});
< /code>
} < /p>
My Java plugin code:
 @Override
public void run(){
try{
//msptCalculator = new SocketOnGetMSPTEvent(); // Initialize the MSPTCalculator instance
listenSock = new ServerSocket(port);

while(true){
sock = listenSock.accept();
in = new DataInputStream(sock.getInputStream());
out = new DataOutputStream(sock.getOutputStream());
this.connect_status = true;
InetAddress addr = sock.getInetAddress();
try{

if(in.readByte() == 1){
int random_code = new SecureRandom().nextInt();

//See on lisatud siia juhuks, kui random_code peaks olema negatiivne. See funktsioon võtab random_codeist
//absoluutväärtuse, mis on alati positiivne.  See on vajalik sellepärast kuna veebipoolel tekib int-i lugemisega
//probleeme kui arv on negatiivne
int random_code_processed = Math.abs(random_code);
Utils.log(Level.INFO, "Random code: "+random_code_processed);

out.writeInt(random_code_processed);
boolean success = Utils.readString(in, false).equals(Utils.hash(random_code_processed + ServerConfig.secretKey));
if(success){ //Kui secret key-ga on korras,
//Kontrollib, kas IP, mis üritab connectida on minu API whitelistis olemas
//Teeme seda siin, et tagada, et IP kontroll oleks alati tehtud, hiljem on võimalik seda bypassida
String incomingIP = addr.getHostAddress();
//Saab incoming connectioni hostnamei
String incomingHostname = addr.getHostName();
if(APIRequest.checkIP(incomingIP, incomingHostname)) { //Kui function returnib true, siis käivitub see kood
//Kõik on korras
out.writeInt(1);
out.flush();
Utils.log(Level.INFO, Utils.format(ServerConfig.successfulLogin));
} else { //Kui connection tuleb teiselt IPlt, siis
//Kui function returnib false ehk vale IP üritab connectida, siis käivitub see kood
Utils.log(Level.ERROR, "A connection from an unknown IP was refused. Please report this to the StatusMC Support staff.  Blocked IP: " + addr.getHostAddress() + " Blocked hostname: "+ addr.getHostName());
out.writeInt(0);
out.flush();
this.connect_status = false;
}
}else{
out.writeInt(0);
out.flush();
Utils.log(Level.INFO, Utils.format(ServerConfig.wrongSecretKey));
this.connect_status = false;
}
}else{
out.writeInt(0);
out.flush();
Utils.log(Level.INFO, Utils.format(ServerConfig.unexpectederror));
this.connect_status = false;
}

while(this.connect_status){
final byte packetNumber = in.readByte();

if(packetNumber == 2) { //GET TPS FUNCTION
double tps = Math.round(SocketOnGetTPSEvent.getTPS() * 100.0D) / 100.0D;
out.writeDouble(tps);
if(ServerConfig.log_performance_metrics.equals(true)) {
Utils.log(Level.INFO, "The current TPS is " + tps + ".");
}

} else if(packetNumber == 4) { //Saab min MSPT
double minMSPTValue = SocketOnGetMSPTEvent.getMinMSPT();
out.writeDouble(minMSPTValue);
if(ServerConfig.log_performance_metrics.equals(true)) {
Utils.log(Level.INFO, "Min MSPT for the last 1 minute: "+minMSPTValue);
}

} else if(packetNumber == 5) { //Saab avg MSPT
double avgMSPTValue = SocketOnGetMSPTEvent.getAvgMSPT();
out.writeDouble(avgMSPTValue);
if(ServerConfig.log_performance_metrics.equals(true)) {
Utils.log(Level.INFO, "Average MSPT for the last 1 minute: "+avgMSPTValue);
}

} else if(packetNumber == 6) { //Saab max MSPT
double maxMSPTValue = SocketOnGetMSPTEvent.getMaxMSPT();
out.writeDouble(maxMSPTValue);
if(ServerConfig.log_performance_metrics.equals(true)) {
Utils.log(Level.INFO, "Max MSPT for the last 1 minute: "+maxMSPTValue);
}

} else if(packetNumber == 3){ // CLOSE_CHANNEL
Utils.log(Level.INFO, "Socket packet 3 close");
out.flush();
closeConnectionGracefully();

} else {
Utils.log(Level.INFO, "Packet not found! Packet: " + packetNumber + " Please contact StatusMC Support staff.");

}
}

}catch(IOException ex){
out.writeDouble(404500); //Kui tekib IO Exception 1, siis writein doublei 404500
//Kui PHP saab tpsi/mspt-d lugeda üritades doublei 404500, siis teeb uue katse lugeda serveri TPSi, sest TPS tekkis viga TPSi
//saamisel. Valisin 404500 sellepärast, et MC serveri TPS JA MSPT ei saa kunagi olla nii suur
out.flush();
/*closeConnectionGracefully();*/
Utils.log(Level.INFO, "IO exception 1: "+ex.getMessage());
ex.printStackTrace();
}

}
}catch(IOException ex){
Utils.log(Level.INFO, "IO exception 2: "+ex.getMessage());
ex.printStackTrace();
}
}

private void closeConnectionGracefully() {
try {
in.close();
out.close();
sock.close();
this.connect_status = false;
} catch (IOException e) {
Utils.log(Level.WARNING, "Error while closing socket connection: "+e.getMessage());
}
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post