I'm new to sockets and network programming and this is my attempt at creating a simple chat server, nothing seems to be wrong with my code (to my knowledge), and it compiles fine but when I try to run it, it seems to get stuck and doesn't do anything.
Apologies if something like this has already been asked, I didn't find anything, but I'm not sure what is wrong so I really don't know what to look for.
Server:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.stage.Stage;
public class ChatServer extends Stage {
TextArea informationArea = new TextArea();
String message = null;
public ChatServer() {
informationArea.setEditable(false);
setTitle("Chat Server");
setScene(new Scene(informationArea, 500, 300));
show();
try {
ServerSocket serverSocket = new ServerSocket(8000);
informationArea.appendText("Server started at " + new Date() + '\n');
int clientNumber = 1;
while(true) {
Socket socket = serverSocket.accept();
InetAddress inetAddress = socket.getInetAddress();
informationArea.appendText(
"Client: " + clientNumber++
+ "\n\thost name: " + inetAddress.getHostName()
+ "\n\tIP address " + inetAddress.getHostAddress() + "\n\n"
);
ClientHandler task = new ClientHandler(socket);
new Thread(task).start();
}
} catch(IOException ex) {
System.err.println(ex);
}
}
class ClientHandler implements Runnable {
private Socket socket;
ClientHandler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
DataInputStream inputFromClient = new DataInputStream(socket.getInputStream());
DataOutputStream outputToClient = new DataOutputStream(socket.getOutputStream());
while (true) {
if (message != null) {
outputToClient.writeUTF(message);
}
message = inputFromClient.readUTF();
}
} catch(IOException e) {
System.err.println(e);
}
}
}
}
Class to run it:
import javafx.application.Application;
import javafx.stage.Stage;
public class RunChatServer extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
stage = new ChatServer();
}
}
I'd appreciate input on what went wrong and why, the proper way to accomplish this goal, and any stylistic advice since this is my very first attempt and I'm unaware of the conventional way to accomplish this.
Update:
I thought maybe it had something to do with holding up the UI thread, I added the import javafx.concurrent.Task and refactored my ClientHandler class like so:
class ClientHandler extends Task {
private Socket socket;
ClientHandler(Socket socket) {
this.socket = socket;
}
@Override
public Void call() {
try {
DataInputStream inputFromClient = new DataInputStream(socket.getInputStream());
DataOutputStream outputToClient = new DataOutputStream(socket.getOutputStream());
while (true) {
if (message != null) {
outputToClient.writeUTF(message);
outputToClient.flush();
}
message = inputFromClient.readUTF();
}
} catch(IOException e) {
System.err.println(e);
}
return null;
}
}
But this didn't fix anything...
Put the loop for the server accepting sockets in its own thread rather than blocking the constructor.
try {
ServerSocket serverSocket = new ServerSocket(8000);
informationArea.appendText("Server started at " + new Date() + '\n');
new Thread(() -> {
int clientNumber = 1;
while (true) {
try {
Socket socket = serverSocket.accept();
InetAddress inetAddress = socket.getInetAddress();
Platform.runLater(() ->
informationArea.appendText(
"Client: " + clientNumber++
+ "\n\thost name: " + inetAddress.getHostName()
+ "\n\tIP address " + inetAddress.getHostAddress() + "\n\n"
)
);
ClientHandler task = new ClientHandler(socket);
new Thread(task).start();
} catch (IOException ex) {
Logger.getLogger(ChatServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}).start();
} catch (IOException ex) {
System.err.println(ex);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With