客户端不从套接字读取数据?

meo*_*cat 5 java sockets networking network-programming server

我花了一段时间阅读其他文章,似乎没有人和我有同样的情况。我尝试了所有未读的解决方案,但没有结果,因此决定创建这个问题。

我一直在处理服务器/客户端应用程序,并且客户端似乎不从套接字读取数据,但是服务器可以读取客户端发送的数据。客户端在尝试读取该行时冻结。这是我的代码:

客户:

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
import java.util.Timer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JLabel;

public class Main {

    public static Socket s = connect();

    public static void sendMessage(String msg) {
        if (s != null) {
            PrintWriter outWriter = null;
            try {
                outWriter = new PrintWriter(s.getOutputStream(), true);
                outWriter.println(msg);
                outWriter.flush();
            } catch (IOException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                outWriter.close();
            } finally {
            }
        } else {
            System.err.println("Error, socket is null!");
        }
    }

    public static String readMessage() {
        if (s != null) {
            Scanner in = null;
            try {
                in = new Scanner(s.getInputStream());
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            String ss = "";
            while (in.hasNext()) {
                ss += in.next();
            }
            System.out.println("REPONSE:" + ss);
            return ss;
        } else {
            System.err.println("Error, socket is null!");
        }
        return "err/readMessage";
    }

    public static Socket connect() {
        try {
            Socket sss = new Socket("localhost", 25586);
            sss.setKeepAlive(true);
            return sss;
        } catch (IOException ex) {
            ex.printStackTrace();
            System.exit(-1);
        }
        return null;
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {

                Thread t = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        sendMessage("HELO");
                        System.out.println("Thread initialized.");

                        while (true) {
                            try {
                                System.out.println("Awaiting message...");
                                Thread.sleep(100);
                                String messages = readMessage();
                                System.out.println("Message recieved! '" + messages + "'");
                                String[] message = messages.split("/");
                                System.out.println(messages);
                                if (message[0].equalsIgnoreCase("DERP")) {                                       // err/reason
                                    System.out.println("IT'S FINALLY WORKING!");
                                } else {
                                    System.out.println("Didn't work :( response:" + messages);
                                }
                            } catch (InterruptedException ex) {
                                ex.printStackTrace();
                            }

                        }
                    }
                });
                t.start();
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

服务器:

import java.util.List;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Main { /* SERVER */


    public static List<EchoThread> list = new ArrayList<>();

    public static int PORT = 25586;

    public static void main(String[] args) throws IOException {
        new Main(PORT);
    }

    public Main(int port) throws IOException {
        this.PORT = port;
        ServerSocket serverSocket = null;
        Socket socket = null;

        try {
            serverSocket = new ServerSocket(PORT);
        } catch (IOException e) {
            e.printStackTrace();

        }
        while (true) {
            try {
                socket = serverSocket.accept();
            } catch (IOException e) {
                System.out.println("I/O error: " + e);
            }
            // new threa for a client
            EchoThread s = new EchoThread(socket);
            s.start();
            list.add(s);
        }
    }

    public static void sendMessageToAll(String ss) {
        for (EchoThread s : list) {
            s.allMessage(ss);
        }
    }
}

class EchoThread extends Thread {

    protected Socket socket;
    InputStream inp = null;
    BufferedReader brinp = null;

    public EchoThread(Socket clientSocket) {
        this.socket = clientSocket;
        try {
            inp = socket.getInputStream();
            brinp = new BufferedReader(new InputStreamReader(inp));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void run() {
        String line;
        while (true) {
            try {
                line = brinp.readLine();
                if ((line == null) || line.equalsIgnoreCase("EXIT")) {
                    socket.close();
                    return;
                } else {
                    handle(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
                return;
            }
        }
    }

    public void handle(String s) {
        String[] keys = s.split("/");
        System.out.println("random: Handling request\"" + s + "\"");
        System.out.println("Response: DERP");
        if (s.equalsIgnoreCase("HELO")) {
            System.out.println("Message recieved:" + s);
        }
        respond("DERP");
    }

    public void respond(String s) {
        try {
            System.out.println("Response_WILLBE:" + s);
            OutputStream os = socket.getOutputStream();
            PrintWriter pw = new PrintWriter(os, true);
            pw.println(s);
            pw.flush();
            System.out.println("Message sent!");
        } catch (Exception ex) {
            Logger.getLogger(EchoThread.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void allMessage(String s) {
        respond(s);
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试了flush()代码并\r\n进行了println修复,但没有一个起作用!-感谢您的阅读!

Ner*_*zle 4

我很好奇客户端和服务器的通信方法之间的差异。例如,客户端使用 aScanner读取输入,而服务器使用 a BufferedReader(这是我个人的偏好)。只是一个建议:保持一致。

现在——首先,客户端仅发送一条消息,但随后开始无限循环地无限读取。鉴于您确切地知道在向服务器发送“HELO”后服务器应如何响应(它应以一行“DERP”响应),因此没有理由以任何形式的循环从服务器读取数据。

服务器上也存在同样的问题。由于客户端现在,它始终只会向服务器发送一行(“HELO”)。因此,服务器应该只期望一行并且只读取一行。绝对没有理由在循环中读取输入。但是,实际问题仅存在于客户端代码中:

目前,您有while(in.hasNext())一个条件,即客户端将从服务器读取输入的时间。hasNext 方法的逻辑功能根据通信方法的不同而不同。在套接字通信的情况下,hasNext需要一个流,因此,除非套接字关闭,否则将始终返回 true。

一般情况下,避免在套接字通信中使用循环,除非您不知道要读取多少行。在这种情况下,您应该首先让发送者向接收者发送某种数字,然后接收者应该在 for 循环中读取后续行,读取“n”次(其中 n 是接收到的数字)。

这是一个非常基本的客户端/服务器通信程序,使用PrintWritersBufferedReaders.

客户

public static void main(String[] args){
    try{
        Socket socket = new Socket("localhost", 12345);
        PrintWriter out = new PrintWriter(socket.getOutputStream());
        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        out.write("HELO\n"); //print("HELO\n") and println("HELO") should work too.
        out.flush();
        System.out.println("Server says " + in.readLine());
        in.close();
        out.close();
        socket.close();
    }catch(IOException e){e.printStackTrace();}
}
Run Code Online (Sandbox Code Playgroud)

服务器

public static void main(String[] args){
    try{
        ServerSocket serverSocket = new ServerSocket(12345);
        while(true){
            new Thread(new ClientConnectionThread(serverSocket.accept())).start();
        }
    }catch(IOException e){e.printStackTrace();}
}

private class ClientConnectionThread implements Runnable{
    private Socket socket;
    public ClientConnectionThread(Socket socket){
        this.socket = socket;
    }
    @Override
    public void run(){
        try{
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintWriter out = new PrintWriter(socket.getOutputStream());
            System.out.println("Client says " + in.readLine());
            out.write("HELO Back!\n"); //again, print("HELO Back!\n") and
                //println("HELO Back!") should also work
            out.flush();
            out.close();
            in.close();
            socket.close();
        }catch(IOException e){e.printStackTrace();}
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,实际通信中不需要循环。