[英]Asynchronous Client Side Java Socket
所以我正在实现一个简单的Java Socket Chat程序,但是我遇到的问题是下面的代码中的问题。 目前,我的客户端代码will first read from socket then output to the screen
, then read from console then output to socket input
。 但是这样一来,我无法从套接字读取消息,直到从控制台读取消息,直到用户按下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();
}
}
}
运行: java ThreadedClient localhost 1982
样本回显服务器
import java.net.*;
import java.io.*;
public class EchoServer {
public static void main(String[] args) throws IOException {
if (args.length != 1) {
System.err.println("Usage: java EchoServer <port number>");
System.exit(1);
}
int portNumber = Integer.parseInt(args[0]);
try (
ServerSocket serverSocket =
new ServerSocket(Integer.parseInt(args[0]));
Socket clientSocket = serverSocket.accept();
PrintWriter out =
new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
) {
String inputLine;
while ((inputLine = in.readLine()) != null) {
out.println("From Server:"+inputLine);
Thread.sleep(2000);
out.println("Server status on");
}
} catch (IOException e) {
System.out.println("Exception caught when trying to listen on port "
+ portNumber + " or listening for a connection");
System.out.println(e.getMessage());
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
在上面的服务器程序中,当客户端中发生用户输入时,添加了手动睡眠和自定义消息以模拟服务器的输出。
运行: java EchoServer 1982
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.