问题
I set up a server/client chat program. What's supposed to happen is a server is setup that can A) read from clients, A2) take what's read from clients and send it to all other clients or B) take input from the console to write to clients. The clients can read from the server and ask it to send messages (which are also read from the console).
There are three files :
- Maim.java (will be used for other purposes later; now is just boilerplate for the Server class)
- Host.java (server)
- Client.java (client)
You're supposed to open one terminal and run Maim which starts a server, then open another terminal and run Client, which runs the client. However, messages are NOT being transmitted between the two, which is odd because
- streams and sockets are being successfully set up and
- if you allow 'null's to be sent ( i.e.: (message = in.readLine()) vs. ((message = in.readLine()) != null) ), 'null's WILL be sent. But only 'null's and nothing else.
Anyways, here's the code :
Maim :
import java.io.*;
import java.util.*;
public class Maim {
static final int port = 9001;
static final String localhost = "localhost";
public static void main(String[] args) throws IOException {
Scanner nameReader = new Scanner(System.in);
System.out.println("What will your name be ? (Currently this feature is unused)");
new Host(nameReader.nextLine()).setUpServer();
}
}
Host :
import java.net.*;
import java.io.*;
import java.util.*;
public class Host {
Socket clientReader;
String name;
private ArrayList<ClientReader> clients;
public Socket getSocket() {
return clientReader;
}
public Host(String name) {
this.name = name;
}
public void setUpServer(){
clients = new ArrayList<ClientReader>();
try {
ServerSocket server = new ServerSocket(Maim.port);
System.out.println("Server set up without fail. Now awaitting clients.");
this.clientReader(server);
} catch (IOException e) {
System.out.println("Failure setting up server on host's network.");
e.printStackTrace();
}
}
public void clientReader(ServerSocket server) {
try {
while (true) {
clientReader = server.accept();
ClientReader newReader = new ClientReader(clientReader);
clients.add(newReader);
Thread newClientThread = new Thread(newReader);
newClientThread.start();
Thread newHostThread = new Thread(new ClientWriter());
newHostThread.start();
System.out.println("New client connection");
}
} catch (IOException e) {
System.out.println("Failure to connect to client.");
e.printStackTrace();
}
}
public void sendAll(String message) {
try {
for (ClientReader client: clients) {
PrintWriter writerToClient = new PrintWriter(client.getSocket().getOutputStream());
writerToClient.println(message);
}
} catch (IOException e) {
System.out.println("Error sending message " + message + " .");
e.printStackTrace();
}
}
public class ClientReader implements Runnable {
private BufferedReader consoleReader;
private Socket server;
public ClientReader(Socket clientSocket) {
try {
server = clientSocket;
consoleReader = new BufferedReader(new InputStreamReader(this.server.getInputStream()));
consoleReader.ready();
System.out.println("Succesfully received client's stream");
} catch(IOException e) {
System.out.println("Error getting input stream from host.");
e.printStackTrace();
}
}
public Socket getSocket() {
return this.server;
}
public void run() {
String newMessage = new String();
try {
while ((newMessage = this.consoleReader.readLine()) != null) {
System.out.println(newMessage);
sendAll(newMessage);
}
} catch(IOException e) {
System.out.println("Error sending client message to clients.");
e.printStackTrace();
}
}
}
public class ClientWriter implements Runnable {
private PrintWriter consoleWriter;
public void run() {
try {
String newMessage;
Scanner consoleReader = new Scanner(System.in);
while (!(newMessage = consoleReader.nextLine()).equals("\n")) {
System.out.println(newMessage);
sendAll(newMessage);
}
} catch(Exception e) {
System.out.println("Error sending host's message to clients.");
e.printStackTrace();
}
}
}
}
Client :
import java.net.*;
import java.io.*;
import java.util.*;
public class Client {
Socket host;
PrintWriter writeToHost;
BufferedReader readFromHost;
public static void main(String[] args) {
new Client().connectToHost();
}
public void connectToHost() {
try {
this.host = new Socket(Maim.localhost,Maim.port);
this.writeToHost = new PrintWriter(host.getOutputStream());
this.readFromHost = new BufferedReader(new InputStreamReader(host.getInputStream()));
this.readFromHost.ready();
System.out.println("Connected to host successfully.");
this.go();
} catch (IOException e) {
System.out.println("Error connecting to host's server.");
e.printStackTrace();
}
}
public void go() {
Thread innerReader = new Thread(new InnerReader());
innerReader.start();
Thread innerWriter = new Thread(new InnerWriter());
innerWriter.start();
}
public class InnerReader implements Runnable {
public void run() {
try {
String message = new String();
while ((message = readFromHost.readLine()) != null) {
System.out.println(message);
}
} catch(Exception e) {
System.out.println("Gotta Catch 'Em All! Insert proper exception string later");
e.printStackTrace();
}
}
}
public class InnerWriter implements Runnable {
public void run() {
try {
Scanner consoleReader = new Scanner(System.in);
String newMessage = new String();
while (!(newMessage = consoleReader.nextLine()).equals("\n")) {
System.out.println(newMessage);
writeToHost.println(newMessage);
}
} catch (Exception e) {
System.out.println("Im so tired and Java's consistent boilerplate is so mind-numbing i can't even synthesize a proper sentence here");
e.printStackTrace();
}
}
}
}
Thanks for the help !
回答1:
You need to flush the PrintWriter
after writing to it:
writerToClient.flush();
This would go in sendAll
in Host
.
回答2:
I suggest flushing your PrintWriter
.
I also suggest disabling Nagel's algorithm via Socket Options. Then even small messages will be sent immediately.
来源:https://stackoverflow.com/questions/21199644/server-client-not-sending-or-receiving-data-through-socket-java