我正在尝试创建一个 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> <span class='error'><br> FAILED Reason: socket_create() - " . socket_strerror(socket_last_error()) . "<br></span>";
} else {
echo "<br> <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> <span class='error'>FAILED <br> Reason: socket_connect() - " . socket_strerror(socket_last_error($socket)) . "<br></span>";
} else {
echo "<br> <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> <span class='error'>FAILED<br> Reason: socket_write() - " . socket_strerror(socket_last_error($socket)) . "<br></span>";
} else {
echo "<br> <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> <span class='error'>FAILED <br> Reason: socket_read() - " . socket_strerror(socket_last_error($socket)) . "<br></span>";
} else {
echo " " . $output . "<br>";
}
// Close Socket
echo "Closing socket...";
socket_close($socket);
echo "<br> <span class='success'>OK</span><br>";
}
else{
echo "Please enter a port number and message.<br>";
}
?>
</div>
</body>
</html>