I'm relatively new to Java and I'm having problems creating a multi-client/server chat.
I need to implement the server to where it can receive multiple messages from one or more clients and it will send all of those messages to all of the clients. So, say there are two clients and client1 sends the message "hi" to the server. The server will send that message to client1 and client2 (it does a send back to all possible clients which are connected to the server).
Also, how do I associate the client's username with their message? If client1 sent "hi", I'd want the TextAreas in Client1 and Client2 that display the messages to say "client1: hi".
The implementations are done in JavaFX.
Server code:
package server;
import java.io.*;
import java.net.*;
import java.util.*;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TextArea;
public class ServerFormController implements Initializable{
@FXML
public TextArea svrLog;
private int clientNo = 0;
ArrayList<HandleAClient> clients = new ArrayList<>();
//@Override
// public void run()
// {
// }
@Override
public void initialize(URL url, ResourceBundle rb) {
new Thread( () ->
{
try{
ServerSocket serverSocket = new ServerSocket(8000);
svrLog.appendText("Server started at " + new Date() + '\n');
while (true)
{
Socket socket = serverSocket.accept();
svrLog.appendText("Worked \n");
clientNo++;
//svrLog.appendText("Starting thread for client " + clientNo + "at"
// + new Date() + '\n');
// InetAddress inetAddress = socket.getInetAddress();
//svrLog.appendText("Client " + clientNo + "'s host name is "
//+ inetAddress.getHostName() + "\n");
// svrLog.appendText("Client " + clientNo + "'s IP Address is "
// + inetAddress.getHostAddress() + "\n");
new Thread(new HandleAClient(socket)).start();
}
} catch (IOException ex) {
svrLog.appendText("Couldn't create ServerSocket! \n");
}
}).start();
}
/** Creates individual client socket*/
class HandleAClient implements Runnable {
private Socket socket;
DataInputStream inputFromClient = null;
DataOutputStream outputToClient = null;
//ServerFormController svr;
public HandleAClient(Socket socket)
{
this.socket = socket;
}
public void run()
{
try{
inputFromClient = new DataInputStream(socket.getInputStream());
outputToClient = new DataOutputStream(socket.getOutputStream());
while (true)
{
String msg = inputFromClient.readUTF();
// for(int i = 0; i < clients.size(); i++) // probably because object in client contain null datastreams
// clients.get(i).outputToClient.writeUTF(msg); // nope.
outputToClient.writeUTF(msg);
svrLog.appendText(msg);
svrLog.appendText("New message received from client. Sent to all clients.");
}
} catch (IOException ex) {
svrLog.appendText("Could not create data stream with client! \n");
}
}
}
}
Client code:
package handlerclient;
import java.io.*;
import java.net.*;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
public class HandlerClientFormController implements Initializable {
@FXML
private TextField ipAdrText; // TextField to get the IP Address
@FXML
private TextField usernameText; // TextField to get the user's chat name
@FXML
private Button clientConnectBtn; // Tries to connect to server
@FXML
private TextArea msgLogTxtArea; // Displays all the messages between the clients
@FXML
private TextArea msgSendTxtArea; // TextArea to get the message from the client
@FXML
private Button clientSendBtn; // Sends the message from the client to the server
DataOutputStream toServer = null;
DataInputStream fromServer = null;
/**
* Initializes the controller class.
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
@FXML
private void onConnectBtnClick(ActionEvent event) {
try{
Socket socket = new Socket(ipAdrText.getText(), 8000);
fromServer = new DataInputStream(socket.getInputStream());
toServer = new DataOutputStream(socket.getOutputStream());
}
catch (IOException ex)
{
msgLogTxtArea.appendText("Could not connect to server!");
}
}
@FXML
private void onSendBtnClick(ActionEvent event) {
try{
toServer.writeUTF(msgSendTxtArea.getText());
toServer.flush();
String newmsg = fromServer.readUTF();
msgLogTxtArea.appendText(newmsg + '\n');
}
catch (IOException ex)
{
msgLogTxtArea.appendText("Could not send/receive message! \n");
}
}
}