简体   繁体   English

Java Socket程序从服务器读回

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

I am trying to implement a simple java server and client - where client sends "hey" and server sends "hello" back. 我正在尝试实现一个简单的Java服务器和客户端-客户端发送“嘿”,服务器发送“你好”。 The problem I am having is even though the server sees hey but client never receives hello. 我遇到的问题是即使服务器看到了嘿,但客户端从未收到问候。 Here is the server code 这是服务器代码

 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();
 }

Client program 客户程序

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();

I have different variations of reading and writing the input/output but with no luck. 我在读写输入/输出方面有不同的变化,但是没有运气。 Suggestions please. 请提出建议。

Thanks 谢谢

This won't work. 这行不通。 IOUtils.toString(input) will read from the input until end of stream, which won't occur until the peer closes the connection, which won't occur at all because he is blocked in readLine() trying to read the response to the request that you are blocked forever reading. IOUtils.toString(input)将从IOUtils.toString(input)读取直到流结束,直到对等方关闭连接时才发生,这根本不会发生,因为他在readLine()被阻止,试图读取对要求您永远被阻止阅读。

Use BufferedReader.readLine() , but without the loop you have in the client. 使用BufferedReader.readLine() ,但不要在客户端中存在循环。

This 这个

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.
}

can be read by 可以被读取

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();
}

When you send messages over sockets you must make sure that you have some kind of "protocol" to delimit your messages. 通过套接字发送消息时,必须确保您具有某种“协议”来分隔消息。 For example by sending a newline after each message. 例如,通过在每条消息后发送换行符。 That way both sides know where messages in a continuous stream of data ends. 这样,双方都知道连续数据流中的消息在何处结束。

Besides sending the right kind message, you also have to make sure to actually send it. 除了发送正确的消息外,您还必须确保实际发送消息。 BufferedWriter for example has a data-buffer and will not send data until the buffer is full enough. 例如, BufferedWriter有一个数据缓冲区,并且在缓冲区足够满之前不会发送数据。 This will in most cases mean that messages will remain in the buffer instead of being sent over the wire. 在大多数情况下,这意味着消息将保留在缓冲区中,而不是通过有线发送。 To do that call flush() once you have written everything you need. 为此,请在编写完所有内容后调用flush()

I have different variations of reading and writing the input/output but with no luck. 我在读写输入/输出方面有不同的变化,但是没有运气。

In your case you don't send a newline but wait for it via readLine . 在您的情况下,您不发送换行符,而是通过readLine等待它。 The client should have actually received the "hello" part but it's not going to return from readLine without newline/end of stream (which should happen if you stop the server at this point). 客户端实际上应该已经收到了"hello"部分,但是在没有换行符/流末尾的情况下,它不会从readLine返回(如果此时停止服务器,则应该发生这种情况)。 The same should apply to the message you send to your server but I guess you do kill the client at this point and therefore see the message. 这同样适用于您发送到服务器的消息,但是我想您此时确实杀死了客户端,因此看到了消息。

Here is also the code I made while playing around with this 这也是我在玩这个游戏时编写的代码

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.

相关问题 Java套接字编程阻止对服务器和客户端的读写 - java socket programming blocking on read and write to and from server&client Java:从HTTP服务器上的套接字读取POST数据 - Java: Read POST data from a socket on an HTTP server 无法读取Java中从套接字服务器发送的数据 - Unable to read data sent from socket server in java 无法使用PHP客户端从Java套接字服务器读取响应 - Cannot read response from Java socket server using PHP client 如果服务器使用写入发送数据并使用readUTF()接收数据,则Java套接字程序无法读取数据 - Java Socket program can not read data if the server sends data using write and recieves data using readUTF() 使用Java中的套接字编程将数据流从客户端程序(在VM中运行)发送到服务器程序(在Host OS上) - Send stream of Data from client program (running in VM) to server program(on Host OS) using socket programming in Java Java程序从服务器中的.ser文件读取对象 - Java program to read objects from a .ser file located in a server 通过Java程序从Linux Server读取文件 - Read a file from Linux Server through java program Java中的服务器程序,并传递对Socket对象的引用 - Server program in Java and passing a reference to a Socket object 从Java套接字读取数据 - Read Data from a Java Socket
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM