异步客户端Java套接字

异步客户端Java套接字,java,sockets,Java,Sockets,因此,我正在实现一个简单的Java套接字聊天程序,但我遇到的问题是,在下面的代码中。当前,我的客户机代码将首先从套接字读取,然后输出到屏幕,然后从控制台读取,然后输出到套接字输入。但是这种方式我无法从套接字打印消息,当它从控制台读取时,直到用户点击enter什么是解决这个问题的最佳方法,是多线程(如果是的话,我可以得到一个例子吗?),还是有其他常规方法来处理这个问题 while(true){ //read from socket, -> output

因此,我正在实现一个简单的Java套接字聊天程序,但我遇到的问题是,在下面的代码中。当前,我的客户机代码
将首先从套接字读取,然后输出到屏幕
然后从控制台读取,然后输出到套接字输入
。但是这种方式我无法从套接字打印消息,当它从控制台读取时,直到用户点击
enter
什么是解决这个问题的最佳方法,是多线程(如果是的话,我可以得到一个例子吗?),还是有其他常规方法来处理这个问题

        while(true){
            //read from socket, -> output to screen
            String line = sockin.readLine();
            System.out.println(line);

            //read console, -> write to socket
            String consolein = consoleReader.readLine();
            sockout.println(consolein);
        }

是的,您应该使用多线程。您需要生成两个线程,一个用于从用户读取输入,另一个用于从服务器/另一个客户端读取输出。但,在基于控制台的聊天应用程序中使用多线程时,有一个问题是:输出和服务器分离,输入和用户分离

示例多线程客户端

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class ThreadedClient {

    public static void main(String[] args) {
        if (args.length != 2) {
            System.err.println(
                    "Usage: java ThreadedClient <host name> <port number>");
            System.exit(1);
        }

        String hostName = args[0];
        int portNumber = Integer.parseInt(args[1]);

        try {
            Socket serverSocket = new Socket(hostName, portNumber);
            ClientServerOutputReader csor = new ClientServerOutputReader(serverSocket);
            csor.start();
            ClientUserInputReader cuir = new ClientUserInputReader(serverSocket);
            cuir.start();
        } catch (UnknownHostException e) {
            System.err.println("Don't know about host " + hostName);
            System.exit(1);
        } catch (IOException e) {
            System.err.println("Couldn't get I/O for the connection to " +
                    hostName);
            System.exit(1);
        } 
    }

}

class ClientServerOutputReader extends Thread {
    Socket serverSocket;
    public ClientServerOutputReader(Socket serverSocket){
        this.serverSocket = serverSocket;
    }

    public void run() {
        try {
            BufferedReader in = new BufferedReader(
            new InputStreamReader(serverSocket.getInputStream()));

            String outputFromServer="";
            while((outputFromServer=in.readLine())!= null){
                //This part is printing the output to console
                //Instead it should be appending the output to some file
                //or some swing element. Because this output may overlap
                //the user input from console
                System.out.println(outputFromServer);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

class ClientUserInputReader extends Thread {
    Socket serverSocket;
    public ClientUserInputReader(Socket serverSocket){
        this.serverSocket = serverSocket;
    }
    public void run(){
        BufferedReader stdIn = new BufferedReader(
                 new InputStreamReader(System.in));
        PrintWriter out;
        try {
            out = new PrintWriter(serverSocket.getOutputStream(), true);
            String userInput;

            while ((userInput = stdIn.readLine()) != null) {
                out.println(userInput);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
在上面的服务器程序中,添加了手动睡眠和自定义消息,以在客户端发生用户输入时模拟服务器的输出


要运行:
JavaEchoServer1982

是的,您应该使用多线程。您需要生成两个线程,一个用于从用户读取输入,另一个用于从服务器/另一个客户端读取输出。但,在基于控制台的聊天应用程序中使用多线程时,有一个问题是:输出和服务器分离,输入和用户分离

示例多线程客户端

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class ThreadedClient {

    public static void main(String[] args) {
        if (args.length != 2) {
            System.err.println(
                    "Usage: java ThreadedClient <host name> <port number>");
            System.exit(1);
        }

        String hostName = args[0];
        int portNumber = Integer.parseInt(args[1]);

        try {
            Socket serverSocket = new Socket(hostName, portNumber);
            ClientServerOutputReader csor = new ClientServerOutputReader(serverSocket);
            csor.start();
            ClientUserInputReader cuir = new ClientUserInputReader(serverSocket);
            cuir.start();
        } catch (UnknownHostException e) {
            System.err.println("Don't know about host " + hostName);
            System.exit(1);
        } catch (IOException e) {
            System.err.println("Couldn't get I/O for the connection to " +
                    hostName);
            System.exit(1);
        } 
    }

}

class ClientServerOutputReader extends Thread {
    Socket serverSocket;
    public ClientServerOutputReader(Socket serverSocket){
        this.serverSocket = serverSocket;
    }

    public void run() {
        try {
            BufferedReader in = new BufferedReader(
            new InputStreamReader(serverSocket.getInputStream()));

            String outputFromServer="";
            while((outputFromServer=in.readLine())!= null){
                //This part is printing the output to console
                //Instead it should be appending the output to some file
                //or some swing element. Because this output may overlap
                //the user input from console
                System.out.println(outputFromServer);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

class ClientUserInputReader extends Thread {
    Socket serverSocket;
    public ClientUserInputReader(Socket serverSocket){
        this.serverSocket = serverSocket;
    }
    public void run(){
        BufferedReader stdIn = new BufferedReader(
                 new InputStreamReader(System.in));
        PrintWriter out;
        try {
            out = new PrintWriter(serverSocket.getOutputStream(), true);
            String userInput;

            while ((userInput = stdIn.readLine()) != null) {
                out.println(userInput);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
在上面的服务器程序中,添加了手动睡眠和自定义消息,以在客户端发生用户输入时模拟服务器的输出


要运行:
JavaEchoServer1982

是的,您应该使用多线程。您需要生成两个线程,一个用于从用户读取输入,另一个用于从服务器/另一个客户端读取输出。但,在基于控制台的聊天应用程序中使用多线程时,有一个问题是:输出和服务器分离,输入和用户分离

示例多线程客户端

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class ThreadedClient {

    public static void main(String[] args) {
        if (args.length != 2) {
            System.err.println(
                    "Usage: java ThreadedClient <host name> <port number>");
            System.exit(1);
        }

        String hostName = args[0];
        int portNumber = Integer.parseInt(args[1]);

        try {
            Socket serverSocket = new Socket(hostName, portNumber);
            ClientServerOutputReader csor = new ClientServerOutputReader(serverSocket);
            csor.start();
            ClientUserInputReader cuir = new ClientUserInputReader(serverSocket);
            cuir.start();
        } catch (UnknownHostException e) {
            System.err.println("Don't know about host " + hostName);
            System.exit(1);
        } catch (IOException e) {
            System.err.println("Couldn't get I/O for the connection to " +
                    hostName);
            System.exit(1);
        } 
    }

}

class ClientServerOutputReader extends Thread {
    Socket serverSocket;
    public ClientServerOutputReader(Socket serverSocket){
        this.serverSocket = serverSocket;
    }

    public void run() {
        try {
            BufferedReader in = new BufferedReader(
            new InputStreamReader(serverSocket.getInputStream()));

            String outputFromServer="";
            while((outputFromServer=in.readLine())!= null){
                //This part is printing the output to console
                //Instead it should be appending the output to some file
                //or some swing element. Because this output may overlap
                //the user input from console
                System.out.println(outputFromServer);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

class ClientUserInputReader extends Thread {
    Socket serverSocket;
    public ClientUserInputReader(Socket serverSocket){
        this.serverSocket = serverSocket;
    }
    public void run(){
        BufferedReader stdIn = new BufferedReader(
                 new InputStreamReader(System.in));
        PrintWriter out;
        try {
            out = new PrintWriter(serverSocket.getOutputStream(), true);
            String userInput;

            while ((userInput = stdIn.readLine()) != null) {
                out.println(userInput);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
在上面的服务器程序中,添加了手动睡眠和自定义消息,以在客户端发生用户输入时模拟服务器的输出


要运行:
JavaEchoServer1982

是的,您应该使用多线程。您需要生成两个线程,一个用于从用户读取输入,另一个用于从服务器/另一个客户端读取输出。但,在基于控制台的聊天应用程序中使用多线程时,有一个问题是:输出和服务器分离,输入和用户分离

示例多线程客户端

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class ThreadedClient {

    public static void main(String[] args) {
        if (args.length != 2) {
            System.err.println(
                    "Usage: java ThreadedClient <host name> <port number>");
            System.exit(1);
        }

        String hostName = args[0];
        int portNumber = Integer.parseInt(args[1]);

        try {
            Socket serverSocket = new Socket(hostName, portNumber);
            ClientServerOutputReader csor = new ClientServerOutputReader(serverSocket);
            csor.start();
            ClientUserInputReader cuir = new ClientUserInputReader(serverSocket);
            cuir.start();
        } catch (UnknownHostException e) {
            System.err.println("Don't know about host " + hostName);
            System.exit(1);
        } catch (IOException e) {
            System.err.println("Couldn't get I/O for the connection to " +
                    hostName);
            System.exit(1);
        } 
    }

}

class ClientServerOutputReader extends Thread {
    Socket serverSocket;
    public ClientServerOutputReader(Socket serverSocket){
        this.serverSocket = serverSocket;
    }

    public void run() {
        try {
            BufferedReader in = new BufferedReader(
            new InputStreamReader(serverSocket.getInputStream()));

            String outputFromServer="";
            while((outputFromServer=in.readLine())!= null){
                //This part is printing the output to console
                //Instead it should be appending the output to some file
                //or some swing element. Because this output may overlap
                //the user input from console
                System.out.println(outputFromServer);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

class ClientUserInputReader extends Thread {
    Socket serverSocket;
    public ClientUserInputReader(Socket serverSocket){
        this.serverSocket = serverSocket;
    }
    public void run(){
        BufferedReader stdIn = new BufferedReader(
                 new InputStreamReader(System.in));
        PrintWriter out;
        try {
            out = new PrintWriter(serverSocket.getOutputStream(), true);
            String userInput;

            while ((userInput = stdIn.readLine()) != null) {
                out.println(userInput);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
在上面的服务器程序中,添加了手动睡眠和自定义消息,以在客户端发生用户输入时模拟服务器的输出


运行:
javaechoserver1982

谢谢,虽然我做了一些类似的子类化线程,但现在我使用Swing输出,解决了问题。谢谢你,虽然我正在做一些类似的子类化线程,但现在我使用Swing输出,这解决了问题。谢谢你,虽然我正在做一些类似的子类化线程,但现在我使用Swing输出,这解决了问题。谢谢你,虽然我正在做一些类似的子类化线程,但现在我使用Swing输出,这解决了问题。谢谢