Java套接字服务器,PHP套接字客户端;沟通工作,但PHP回声'仅在套接字连接关闭后才能生成数据

时间:2014-04-03 09:02:47

标签: java php sockets communication

我正在尝试在基于Java的套接字服务器和基于PHP的套接字客户端之间创建基于套接字的简单服务器/客户端通信。我按预期得到了所有回复,但没有立即回复。这是我想要做的。 PHP客户端向Java服务器发送命令,它会回复一个答案。这个答案应该立即显示在PHP页面上。然后发送第二个命令,服务器再次发送应立即显示的响应。但就我而言,回复是“回应”。仅在整个基于套接字的通信终止后。那是在我从PHP客户端关闭套接字连接之后。

以下是我的Java套接字服务器代码:

    public class MultiThreadServer implements Runnable {
        Socket csocket;

        MultiThreadServer(final Socket csocket) {
            this.csocket = csocket;
        }

        private static void download(final String url) {
            try {
                final URL downloadURL = new URL(url);
                URLConnection conn = null;
                try {
                    conn = downloadURL.openConnection();
                    final InputStream inputStream = conn.getInputStream();
                    final long filesize = conn.getContentLength();
                    System.out.println("Size of file : " + (filesize / 1024)
                            + " (kb)");
                    final FileOutputStream outputStream = new FileOutputStream(
                            System.getProperty("user.dir") + "/test.exe");
                    final long startTime = System.currentTimeMillis();
                    final byte[] buffer = new byte[1024];
                    int bytesRead = -1;
                    while ((bytesRead = inputStream.read(buffer)) != -1) {
                        outputStream.write(buffer, 0, bytesRead);
                    }
                    final long endTime = System.currentTimeMillis();
                    System.out.println("File downloaded");
                    System.out.println("Download time in sec. is : "
                            + ((endTime - startTime) / 1000));
                    outputStream.close();
                    inputStream.close();
                } catch (final IOException e) {
                    e.printStackTrace();
                }
            } catch (final MalformedURLException e) {
                e.printStackTrace();
            }
        }

        public static void main(final String args[]) throws Exception {
            final ServerSocket ssock = new ServerSocket(3333);
            System.out.println("Listening on " + ssock.toString());
            while (true) {
                final Socket sock = ssock.accept();
                System.out.println("Connected to " + sock.getRemoteSocketAddress());
                new Thread(new MultiThreadServer(sock)).start();
            }
        }

        @Override
        public void run() {
            try {
                final BufferedReader br = new BufferedReader(new InputStreamReader(
                        this.csocket.getInputStream()));
                final BufferedWriter bw = new BufferedWriter(
                        new OutputStreamWriter(this.csocket.getOutputStream()));
                bw.write(this.csocket.getRemoteSocketAddress().toString()
                        .replace("/", "")
                        + "\n");
                bw.flush();
                String line;
                while ((line = br.readLine()) != null) {
                    if (line.equalsIgnoreCase("getMacName")) {
                        final String macName = InetAddress.getLocalHost()
                                .getHostName();
                        bw.write(macName + "\n");
                        bw.flush();
                        System.out.println("Machine Name : " + macName);
                    } else if (line.equalsIgnoreCase("getMacIP")) {
                        final String macIP = InetAddress.getLocalHost()
                                .getHostAddress();
                        bw.write(macIP + "\n");
                        bw.flush();
                        System.out.println("Machine IP : " + macIP);
                    } else if (line.equalsIgnoreCase("getCurrentVersion")) {
                        final String currVersion = "0.1a";
                        bw.write(currVersion + "\n");
                        bw.flush();
                        System.out.println("Current Version : " + currVersion);
                    } else if (line
                            .equalsIgnoreCase("downUrl:http://webserver/webapp/test.exe")) {
                        final String url = line.substring(8);
                        bw.write("Downloading : " + url + "\n");
                        bw.flush();
                        MultiThreadServer.download(url);
                        System.out.println("URL : " + url);
                    } else if (line.equalsIgnoreCase("exit")) {
                        bw.write("Closing\n");
                        bw.flush(); 
                        bw.close();
                        br.close();
                        System.out.println("Exiting!");
                        this.csocket.close();
                        break;
                    }
                }
            } catch (final IOException e) {
                e.printStackTrace();
            }
        }
    }

以下是我的示例PHP客户端源代码:

<html>
<head>
<title>Socket Connection Test</title>
</head>
<body>
<h3>Testing Socket Connection</h3>
<br>
<?php
$host="127.0.0.1";
$port = 3333;
$fp;
$macName;
$macIP;
$message;
$result;

// open a client connection
$fp = fsockopen ($host, $port, $errno, $errstr);

if (!$fp)
{
$result = "Error: Could not open socket connection! Error No: " . $errno . ". Error String: " . $errstr;
die($result);
}
else
{
$message = fgets ($fp, 1024);
$message = trim($message);
echo "Connected to remote server on current port : " . $message;
echo "<br>";
sleep(5);

// get machine name
fwrite ($fp, "getMacName\n");
$macName = fgets ($fp, 1024);
$macName = trim($macName);
echo "Machine Name : " . $macName;
echo "<br>";
sleep(5);

// get IP address
fwrite ($fp, "getMacIP\n");
$macIP = fgets ($fp, 1024);
$macIP = trim($macIP);
echo "Machine IP : " . $macIP;
echo "<br>";
sleep(5);

fwrite ($fp, "getCurrentVersion\n");
$currVersion = fgets ($fp, 1024);
$currVersion = trim($currVersion);
echo "Current Version : " . $currVersion;
echo "<br>";
sleep(5);

fwrite ($fp, "downUrl:http://webserver/webapp/text.exe\n");
$downResponse = fgets ($fp, 1024);
$downResponse = trim($downResponse);
echo "Download Response : " . $downResponse;
echo "<br>";
sleep(5);

fwrite ($fp, "exit\n");
$exitStatus = fgets ($fp, 1024);
fclose ($fp);
echo "Connection Closed.";
}
?>
</body>
</html>

在这种情况下,最后会显示整个PHP输出。我甚至尝试将睡眠放在不同的地方,但是在写入输出之前似乎正在等待套接字连接关闭。我怎样才能获得输出&#34; LIVE&#34;。喜欢正常的聊天交流?我在这里做错了什么?

2 个答案:

答案 0 :(得分:1)

你的脚本运行正常,并且对你正在寻找的东西没有什么大的缺陷。由于从命令行而不是Web浏览器运行脚本时获得了所需的结果,因此我们可以查明问题的原因:HTTP协议

HTTP不是用于持续连接(就像你习惯使用Java套接字一样),但它的简化工作流程基于Request / Elaborate / Response / Forget。因此,您无法与纯HTML / PHP over HTTP解决方案进行“实时聊天”。

唉,不是所有的希望都失去了!要实现“实时”通信,您可以使用Ajax,这不是很难习惯。我说过“直播”,因为它仍然是一个基于HTTP的解决方案,但至少你可以在同一个网页内收到请求和接收响应,这是HTML / PHP / AJAX三元组最接近的。

答案 1 :(得分:-1)

看起来你好不懂php的http。 只有在php客户端代码完成执行后,才会获得HTML响应。 (即)你所有的回声将被放置在你指定的地方并作为一个整体返回。 放睡只会延迟执行。