繁体   English   中英

Java Socket程序从服务器读回

[英]Java Socket program to read back from the server

我正在尝试实现一个简单的Java服务器和客户端-客户端发送“嘿”,服务器发送“你好”。 我遇到的问题是即使服务器看到了嘿,但客户端从未收到问候。 这是服务器代码

 try {
                    InputStream input = clientSocket.getInputStream();

                    System.out.println("client's request"+ IOUtils.toString(input));

                    OutputStream output = clientSocket.getOutputStream();
                    PrintWriter pw = new PrintWriter(output);
                    pw.write("hello");
                    pw.flush();
                    /*BufferedOutputStream bf = new BufferedOutputStream(output);
                    bf.write("hello".getBytes());*/
                    /*output.write(("hello").getBytes());*/

                    long time = System.currentTimeMillis();

                    System.out.println("Request processed: " + time);

 } 
 catch (IOException e) 
 {
                    // report exception somewhere.
                    e.printStackTrace();
 }

客户程序

Socket s = new Socket("localhost",9000);

OutputStream out = s.getOutputStream();
out.write("hey".getBytes());
/*PrintWriter pw = new PrintWriter(out);
pw.write("hey");
pw.flush(); */

BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));


String line;
while((line =br.readLine())!= null)
{
    System.out.println(line);
}
s.close();

我在读写输入/输出方面有不同的变化,但是没有运气。 请提出建议。

谢谢

这行不通。 IOUtils.toString(input)将从IOUtils.toString(input)读取直到流结束,直到对等方关闭连接时才发生,这根本不会发生,因为他在readLine()被阻止,试图读取对要求您永远被阻止阅读。

使用BufferedReader.readLine() ,但不要在客户端中存在循环。

这个

void writeLine(BufferedWriter writer, String text) throws IOException {
    writer.write(text); // the actual characters we want to send
    writer.newLine();   // something that signals the end of the message.
    writer.flush();     // and we must enforce that these bytes are sent and not buffered locally.
}

可以被读取

String readLine(BufferedReader reader) throws IOException {
    // reads characters until it finds either a newline or end of stream
    // returns data or null when the stream has already ended
    return reader.readLine();
}

通过套接字发送消息时,必须确保您具有某种“协议”来分隔消息。 例如,通过在每条消息后发送换行符。 这样,双方都知道连续数据流中的消息在何处结束。

除了发送正确的消息外,您还必须确保实际发送消息。 例如, BufferedWriter有一个数据缓冲区,并且在缓冲区足够满之前不会发送数据。 在大多数情况下,这意味着消息将保留在缓冲区中,而不是通过有线发送。 为此,请在编写完所有内容后调用flush()

我在读写输入/输出方面有不同的变化,但是没有运气。

在您的情况下,您不发送换行符,而是通过readLine等待它。 客户端实际上应该已经收到了"hello"部分,但是在没有换行符/流末尾的情况下,它不会从readLine返回(如果此时停止服务器,则应该发生这种情况)。 这同样适用于您发送到服务器的消息,但是我想您此时确实杀死了客户端,因此看到了消息。

这也是我在玩这个游戏时编写的代码

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.CountDownLatch;

class Hello {

    static int port = 12345;

    private static void writeLine(BufferedWriter writer, String line) throws IOException {
        System.out.println(">> " + line);
        writer.write(line); // the actual characters that we want to send
        writer.newLine();   // something that signals the end of the message.
        writer.flush();     // and we must enforce that these bytes are sent and not buffered locally.
    }

    private static String readLine(BufferedReader reader) throws IOException {
        // reads characters until it finds either a newline or the end of the stream
        // returns data or null when the stream has already ended
        return reader.readLine();
    }

    static void handle(Socket cs, boolean controlling) {
        try (Socket socket = cs) {
            try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                 BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {

                if (controlling) {
                    writeLine(writer, "hey");
                }

                loop: while (!Thread.currentThread().isInterrupted()) {

                    String readLine = readLine(reader);
                    System.out.println("<< " + readLine);

                    if (readLine == null)
                        break;

                    switch (readLine) {
                        case "hey":
                            writeLine(writer, "ho");
                            break;
                        case "ho":
                            writeLine(writer, "bye");
                            break;
                        case "bye":
                            break loop;
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    static void server(CountDownLatch latch) {
        try (ServerSocket ss = new ServerSocket(port)) {
            System.out.println("Listening.");
            latch.countDown();
            while (!Thread.currentThread().isInterrupted()) {
                Socket clientSocket = ss.accept();
                // spawn a new thread per client
                new Thread(() -> handle(clientSocket, false)).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    static void client() {
        System.out.println("Connecting.");
        try (Socket socket = new Socket("localhost", port)) {
            System.out.println("Connected.");
            handle(socket, true);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(1);
        new Thread(() -> server(latch)).start();
        latch.await();
        new Thread(() -> client()).start();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM