我有一个经典的客户端/服务器设置为从客户端接收一个简单的数学问题,计算服务器中的结果,然后将结果发送回所有连接的客户端。但在客户端,我似乎错过了某处的阅读;在我向第二个客户端输入内容之后,来自第一个客户端的消息仅返回给第二个客户端,反之亦然。我希望能够将所有消息发送到每个客户端,而无需先输入内容。
Sever代码:
import java.net.*;
import java.util.*;
import java.io.*;
public class EchoServer2 extends Thread{
protected Socket clientSocket;
static String [] logs = new String[100];
private static ArrayList<PrintWriter> writers = new ArrayList<PrintWriter>();
static int arrayPos = 0;
static int i;
static String message;
public static void main(String[] args) throws IOException{
ServerSocket serverSocket = null;
try{
serverSocket = new ServerSocket(10008);
System.out.println ("Connection Socket Created");
try {
while (true)
{
System.out.println ("Waiting for Connection");
new EchoServer2 (serverSocket.accept());
}
}
catch (IOException e)
{
System.err.println("Accept failed.");
System.exit(1);
}
}
catch (IOException e)
{
System.err.println("Could not listen on port: 10008.");
System.exit(1);
}
finally{
try{
serverSocket.close();
}
catch (IOException e)
{
System.err.println("Could not close port: 10008.");
System.exit(1);
}
}
}
private EchoServer2 (Socket clientSoc){
clientSocket = clientSoc;
start();
}
public void run(){
System.out.println ("New Communication Thread Started");
try{
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(),
true);
writers.add(out);
BufferedReader in = new BufferedReader(new InputStreamReader( clientSocket.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) { //reading
logs[arrayPos] = inputLine; //keep record of all commands sent to server
arrayPos++; //update array position
if (inputLine.equals("Bye.")) //break if client enters 'Bye."
break;
if(inputLine.equals("Logs.")){ //print out contents of logs if any client enters 'Logs'
for(i=0; i<arrayPos; i++){
System.out.println("Log"+ i + ": " + logs[i]);
out.println("Log"+ i + ": " + logs[i]);
}
break;
}
int x, y, result;
String num1, num2, operator;
String [] splitStrings = inputLine.split(" ");
num1 = splitStrings[0];
x = Integer.parseInt(num1);
operator = splitStrings[1];
num2 = splitStrings[2];
y = Integer.parseInt(num2);
switch(operator){
case "+":
result = x + y;
System.out.println ("Server: " + result);
out.println(result);
for (PrintWriter writer : writers) {
if (writer == out)
continue;
writer.println(result);
}
break;
case "-":
result = x - y;
System.out.println ("Server: " + result);
out.println(result);
for (PrintWriter writer : writers) {
if (writer == out)
continue;
writer.println(result);
}
break;
case "*":
result = x * y;
System.out.println ("Server: " + result);
out.println(result);
for (PrintWriter writer : writers) {
if (writer == out)
continue;
writer.println(result);
}
break;
case "/":
result = x / y;
System.out.println ("Server: " + result);
out.println(result);
for (PrintWriter writer : writers) {
if (writer == out)
continue;
writer.println(result);
}
break;
default:
System.out.println("Please enter a more simple equation using one of the 4 main operators i.e. '+, -, *, /'");
break;
}
}
out.flush();
out.close();
in.close();
clientSocket.close();
}
catch (IOException e){
System.err.println("Problem with Communication Server");
System.exit(1);
}
}
}
客户代码:
import java.io.*;
import java.net.*;
public class EchoClient{
public static void main(String[] args) throws IOException{
String serverHostname = new String ("127.0.0.1");
if (args.length > 0)
serverHostname = args[0];
System.out.println ("Attemping to connect to host " + serverHostname + " on port 10008.");
Socket echoSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try{
// echoSocket = new Socket("taranis", 7);
echoSocket = new Socket(serverHostname, 10008);
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
}catch (UnknownHostException e){
System.err.println("Don't know about host: " + serverHostname);
System.exit(1);
} catch (IOException e){
System.err.println("Couldn't get I/O for " + "the connection to: " + serverHostname);
System.exit(1);
}
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String userInput;
System.out.println ("Type Message (\"Bye.\" to quit)");
System.out.println("Enter a simple math equation i.e. 2 + 2 separated by a space…");
while ((userInput = stdIn.readLine()) != null){
out.println(userInput);
userInput = in.readLine();
System.out.println("echo: " + userInput);
while(in.ready()){
userInput = in.readLine();
System.out.println("echo: " + userInput);
}
System.out.println("Enter a simple math equation e.g. 2 + 2 separated by a space…");
}
out.close();
in.close();
stdIn.close();
echoSocket.close();
}
}
关于这个主题有很多答案,但似乎没有一个对我的方式有效。
所有建议都表示赞赏。
**我知道我的代码目前并不是非常优雅,但在这个阶段它只是一个让它工作然后从那里整理起来的情况。
解决
客户端的while循环需要改变
while(true){
if(userInput == null){
System.out.println("Input is null");
}
if(userInput.equals("Bye.")){
break;
}
if(stdIn.ready()){//(userInput = stdIn.readLine()) != null){
userInput = stdIn.readLine();
out.println(clientID + "\t" + userInput);
userInput = in.readLine();
System.out.println("echo: " + userInput);
System.out.println("Enter a simple math equation e.g. 2 + 2 separated by a space…");
out.flush();
}
else if(in.ready()){
userInput = in.readLine();
System.out.println("echo: " + userInput);
//System.out.println("Enter a simple math equation e.g. 2 + 2 separated by a space…");
out.flush();
}
}
我还对代码进行了一些其他调整,因此为什么会增加变量等等!
答案 0 :(得分:1)
您需要同时处理输入和输出。一种选择是使用单独的线程。
现在,您的客户端和服务器按顺序阻止输入从一个到另一个的输入。
这种多线程需要在服务器和客户端上。服务器每个连接的客户端需要两个线程(一个用于输入,一个用于输出),客户端需要相同但仅用于与服务器的单个连接。