I'm trying to make a very simple chat program that can accommodate multiple clients. I have a multi-threaded server and can connect multiple clients to it, but the server only communicates with a single client (as it should, each client is on its own thread) I need help getting the server to send all messages from all connected clients to each client. I think I'd need to share a single object between threads? Here's the code:
server:
import java.net.ServerSocket;
import java.net.Socket;
public class ThreadedCommandServer {
public static void main(String[] args) throws Exception {
System.out.println("Starting server....");
int port = 8989;
ServerSocket ss = new ServerSocket(port);
while(true) {
System.out.println("Waiting for connection from client...");
Socket socket = ss.accept();
ServerThread st = new ServerThread(socket);
st.start();
}
}
}
server thread:
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
public class ServerThread extends Thread {
private Socket socket = null;
private String s;
public ServerThread(Socket s) {
socket = s;
}
public void run() {
try {
InputStream is = socket.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
s = (String) ois.readObject();
System.out.println("received string: " + s);
OutputStream os = socket.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(s);
System.out.println("sent object back to client...");
} catch (Exception e) {
System.out.println(e.toString());
}
}
}
client:
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
public class Controller {
private ClientFrame cf;
private String message;
private Socket socket;
private String response;
public Controller(ClientFrame cf) {
this.cf = cf;
}
public void sendChat(String s) {
message = s;
System.out.println("FROM CONTROLLER: received: " + message);
try {
InetAddress i = InetAddress.getByName("localhost");
socket= new Socket(i, 8989);
OutputStream os = socket.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
System.out.println("FROM CONTROLLER: sending message to the server...");
oos.writeObject(message);
InputStream is = socket.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
System.out.println("getting string back from server....");
response = (String) ois.readObject();
cf.updateGUI(response);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
GUI:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ClientFrame extends JFrame {
private JTextArea chatArea;
private JTextField type;
private JButton submit;
private JPanel upper;
private JPanel lower;
private BorderLayout bl;
JScrollPane jsp;
Controller c;
public ClientFrame() {
bl = new BorderLayout();
upper = new JPanel();
lower = new JPanel();
chatArea = new JTextArea("chat goes here", 20, 30);
c = new Controller(this);
chatArea.setEditable(false);
chatArea.setLineWrap(true);
type = new JTextField("type here", 20);
jsp = new JScrollPane(chatArea);
new SmartScroller(jsp);
lower.add(type);
submit = new JButton("send");
submit.addActionListener(new Submit());
type.addActionListener(new Submit());
lower.add(submit);
upper.add(jsp);
this.setSize(400, 600);
this.setLayout(bl);
this.setTitle("MattChatt");
this.add(upper, BorderLayout.NORTH);
this.add(lower, BorderLayout.SOUTH);
this.setVisible(true);
this.setResizable(false);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void updateGUI(String s) {
chatArea.append("\n" + s);
}
private class Submit implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if (type.getText().equals("")) {
System.out.println("no text entered");
} else {
System.out.println("submitted");
c.sendChat(type.getText());
type.setText("");
}
}
}
}
You have no way of accessing all of the ServerThreads you create.
What you need to do is group them all together in a collection, such as an ArrayList.
Or even better, a HashMap, if you would ever want to expand your application to allow private messaging, you would need to access a specific ServerThread, and with a HashMap you can do so easily.
Anyways... when it is time to send out the message, you should loop your collection through and send the message to the OutputStreams associated with each ServerThread.
Related
I have a server client application working just how I want it locally. I need to get the server online so the client program can be used from different computers. Not sure how to do this. I have my own website that I thought I could just put the Server on in the background.
Is this possible or am I just looking at this the wrong way.
Server.java
package core;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Scanner;
public class Server {
public static void main(String[] args) throws IOException {
ArrayList<ClientHandler> clients = new ArrayList<>();
ServerSocket serverSocket = null;
int clientNum = 1; // keeps track of how many clients were created
// 1. CREATE A NEW SERVERSOCKET
try {
serverSocket = new ServerSocket(4444); // provide MYSERVICE at port
// 4444
} catch (IOException e) {
System.out.println("Could not listen on port: 4444");
System.exit(-1);
}
// 2. LOOP FOREVER - SERVER IS ALWAYS WAITING TO PROVIDE SERVICE!
while (true) {
Socket clientSocket = null;
try {
// 2.1 WAIT FOR CLIENT TO TRY TO CONNECT TO SERVER
System.out.println("Waiting for client " + clientNum + " to connect!");
clientSocket = serverSocket.accept();
clientNum++;
ClientHandler c = new ClientHandler(clientSocket, clients);
clients.add(c);
// 2.2 SPAWN A THREAD TO HANDLE CLIENT REQUEST
Thread t = new Thread(c);
t.start();
} catch (IOException e) {
System.out.println("Accept failed: 4444");
System.exit(-1);
}
// 2.3 GO BACK TO WAITING FOR OTHER CLIENTS
// (While the thread that was created handles the connected client's
// request)
} // end while loop
} // end of main method
} // end of class MyServer
class ClientHandler implements Runnable {
Socket s; // this is socket on the server side that connects to the CLIENT
ArrayList<ClientHandler> others;
Scanner in;
PrintWriter out;
ClientHandler(Socket s, ArrayList<ClientHandler> others) throws IOException {
this.s = s;
this.others = others;
in = new Scanner(s.getInputStream());
out = new PrintWriter(s.getOutputStream());
}
/*
* (non-Javadoc)
*
* #see java.lang.Runnable#run()
*/
public void run() {
// 1. USE THE SOCKET TO READ WHAT THE CLIENT IS SENDING
while (true) {
String clientMessage = in.nextLine();
// System.out.println(clientMessage);
new Thread(new Runnable() {
#Override
public void run() {
try (PrintWriter fileWriter = new PrintWriter(new FileOutputStream(new File("chat.txt"), true));) {
fileWriter.println(clientMessage);
fileWriter.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// System.out.println(others.size());
for (ClientHandler c : others) {
// System.out.println(c.toString());
c.sendMessage(clientMessage);
}
}
}).start();
}
}
private void sendMessage(String str) {
out.println(str);
out.flush();
}
} // end of class ClientHandler
ClientSide.java
package core;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.BoxLayout;
import javax.swing.JTextArea;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JButton;
public class ClientSide extends JFrame {
private JPanel contentPane;
private JTextField textField;
private String name;
private JTextArea textArea;
private Thread serverListener;
private Socket socket;
private Scanner in;
private PrintWriter out;
// /**
// * Launch the application.
// */
// public static void main(String[] args) {
// EventQueue.invokeLater(new Runnable() {
// public void run() {
// try {
// ClientSide frame = new ClientSide();
// frame.setVisible(true);
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
// });
// }
/**
* Create the frame.
*
* #throws IOException
*/
public ClientSide(String myName) {
try {
socket = new Socket("localhost", 4444);
in = new Scanner(socket.getInputStream());
out = new PrintWriter(socket.getOutputStream());
} catch (IOException e1) {
e1.printStackTrace();
}
serverListener = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
String clientMessage = in.nextLine();
try {
System.out.println("Receiving before dec: " + clientMessage);
clientMessage = Crypto.decrypt(clientMessage, "key");
System.out.println("Receiving after dec: " + clientMessage);
addLine(clientMessage);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
serverListener.start();
name = myName;
setTitle("Client Side");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
JPanel topPanel = new JPanel();
FlowLayout flowLayout = (FlowLayout) topPanel.getLayout();
flowLayout.setAlignment(FlowLayout.LEFT);
contentPane.add(topPanel);
textArea = new JTextArea();
textArea.setEditable(false);
textArea.setColumns(20);
textArea.setRows(7);
topPanel.add(textArea);
JPanel bottomPanel = new JPanel();
contentPane.add(bottomPanel);
bottomPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));
JLabel lblMessage = new JLabel("Message");
bottomPanel.add(lblMessage);
textField = new JTextField();
bottomPanel.add(textField);
textField.setColumns(10);
JButton btnSend = new JButton("Send");
btnSend.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// send string/message to server
String clientMessage;
try {
clientMessage = Crypto.encrypt(name + ": > " + textField.getText(), "key");
System.out.println("Sending: " + clientMessage);
out.println(clientMessage);
out.flush();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
bottomPanel.add(btnSend);
}
public void addLine(String text) {
textArea.setText(textArea.getText() + text + "\n");
}
}
Provided your ClientSide class connects with your server applicztion on port 4444, you can do the following:
Package your client as jar file and run on each computer you want to distribute it to.
Ensure, each of those computers have JRE installed.
3 Package your Server module as jar file
You should own your server or have admin right. So you can install Java if not there.
Depending on OS, SSH skill might be required
Ensure PORT 4444 is enabled on your host server. firewall
Get the public IP address of your server and use it in your ClideSide code.
hi everyone i have problems with sending 2 strings via socket in java.
i have UI that get Username and password from client and send it to server . my problem make 2 part :1-i can not get the string username in my server 2- when the client send the username the socket is close before send the password here is my code please help me .
the main purpose is getting 2 string username and password from UI (client)and send them by socket to server.
Server:
package finalproject;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Server
{
ServerSocket listener;
Socket socket;
OutputStream out ;
InputStream in;;
InputStreamReader reader;
OutputStreamWriter writer;
String massage;
public void connectserver() throws IOException
{
listener = new ServerSocket(9097);
System.out.println("Server is running on port 9097 ...");
}
public void waitforclient() throws IOException
{
socket = listener.accept();
System.out.println("A new client connected to the server");
}
public void startstreamsserver() throws IOException
{
in = socket.getInputStream();
out = socket.getOutputStream();
writer = new OutputStreamWriter(out);
reader = new InputStreamReader(in);
System.out.println("Server streams are ready");
}
public void closestreamsserver() throws IOException
{
writer.close();
reader.close();
}
public void getinfoserver() throws IOException
{
try
{
reader.read();
System.out.println(reader);
System.out.println("input is : " + reader.toString());
}
catch(IOException IOE)
{
IOE.printStackTrace();//if there is an error, print it out
}
}
}
Client:
package finalproject;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Client
{
Socket socket;
OutputStream out1;
InputStream in1;
OutputStreamWriter writer;
InputStreamReader reader;
String massage;
JFrame frame;
BorderLayout blayout;
JButton center;
JButton south;
FlowLayout fLoyout;
JLabel jb1;
JTextField name;
JLabel jb2;
JTextField pass;
JLabel jb7;
JPanel cpanel;
JPanel spanel;
public void connectclient() throws IOException
{
socket = new Socket("localhost", 9097);
System.out.println("connect to server on port 9097");
}
public void startstreamsclient() throws IOException
{
in1 = socket.getInputStream();
out1 = socket.getOutputStream();
writer = new OutputStreamWriter(out1);
reader = new InputStreamReader(in1);
System.out.println("Client streams are ready");
}
public void closestreamsclient() throws IOException
{
writer.close();
reader.close();
}
public void loginformclient()
{
frame = new JFrame();
frame.setVisible(true);
frame.setSize(500, 600);
blayout = new BorderLayout();
center = new JButton();
south = new JButton();
frame.setLayout(blayout);
fLoyout = new FlowLayout(FlowLayout.CENTER);
center.setLayout(fLoyout);
south.setLayout(fLoyout);
jb1 = new JLabel("Username :");
name = new JTextField(20);
center.add(jb1);
center.add(name);
jb2 = new JLabel("Password :");
pass = new JTextField(30);
center.add(jb2);
center.add(pass);
jb7 = new JLabel("Save");
south.add(jb7);
cpanel = new JPanel();
cpanel.add(center);
spanel = new JPanel();
south.addActionListener((ActionEvent ae) -> {
try
{
writer.write(name.getText());
writer.flush();
writer.write(pass.getText());
writer.flush();
writer.close();
}
catch (IOException ex)
{
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
});
spanel.add(south);
cpanel.setLayout(new BoxLayout(cpanel, BoxLayout.Y_AXIS));
frame.add(cpanel, BorderLayout.CENTER);
frame.add(spanel, BorderLayout.SOUTH);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
and my main class :
package finalproject;
import java.io.IOException;
import javax.swing.JFrame;
public class Finalproject
{
public static void main(String[] args) throws IOException
{
//build Server & Client
Server server = new Server();
Client client = new Client();
//Start Server & Client
server.connectserver();
client.connectclient();
//Server wait for new connection
server.waitforclient();
//start the Streams
client.startstreamsclient();
server.startstreamsserver();
//Client send login information to Server
client.loginformclient();
//Server get information
server.getinfoserver();
}
}
but the my inputs in my server are:
java.io.InputStreamReader#171fc7e
input is : java.io.InputStreamReader#171fc7e
Edited Based on EJP correct remark:
Add new line delimiter:
writer.write(name.getText() + System.lineSeparator());
writer.write(pass.getText());
writer.flush();
replace this:
reader = new InputStreamReader(in);
System.out.println("Server streams are ready");
with:
BufferedReader in = new BufferedReader(reader);
String username= in.readLine();
String password = in.readLine();
Hello I am having trouble with getting both the server and the clients connecting to each other when they are not on the same network. Please could you have a look at the code and see what I need to do to fix this issue.
I am new at Java and with the whole networking side of things so any help would be appreciated.
Server
>!
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashSet;
public class ChatServer {
private static final int PORT = 9001;
private static HashSet<String> names = new HashSet<String>();
private static HashSet<PrintWriter> writers = new HashSet<PrintWriter>();
public static void main(String[] args) throws Exception {
System.out.println("The chat server is running.");
ServerSocket listener = new ServerSocket(PORT);
try {
while (true) {
new Handler(listener.accept()).start();
}
} finally {
listener.close();
}
}
private static class Handler extends Thread {
private String name;
private Socket socket;
private BufferedReader in;
private PrintWriter out;
public Handler(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
try {
// Create character streams for the socket.
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
// Request a name from this client. Keep requesting until
// a name is submitted that is not already used. Note that
// checking for the existence of a name and adding the name
// must be done while locking the set of names.
while (true) {
out.println("SUBMITNAME");
name = in.readLine();
if (name == null) {
return;
}
synchronized (names) {
if (!names.contains(name)) {
names.add(name);
break;
}
}
}
// Now that a successful name has been chosen, add the
// socket's print writer to the set of all writers so
// this client can receive broadcast messages.
out.println("NAMEACCEPTED");
writers.add(out);
// Accept messages from this client and broadcast them.
// Ignore other clients that cannot be broadcasted to.
while (true) {
String input = in.readLine();
if (input == null) {
return;
}
for (PrintWriter writer : writers) {
writer.println("MESSAGE " + name + ": " + input);
}
}
} catch (IOException e) {
System.out.println(e);
} finally {
// This client is going down! Remove its name and its print
// writer from the sets, and close its socket.
if (name != null) {
names.remove(name);
}
if (out != null) {
writers.remove(out);
}
try {
socket.close();
} catch (IOException e) {
}
}
}
}
}
Client
>!
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ChatClient {
BufferedReader in;
PrintWriter out;
JFrame frame = new JFrame("Messager");
JTextField textField = new JTextField(40);
JTextArea messageArea = new JTextArea(8, 40);
public ChatClient() {
// Layout GUI
textField.setEditable(false);
messageArea.setEditable(false);
frame.getContentPane().add(textField, "North");
frame.getContentPane().add(new JScrollPane(messageArea), "Center");
frame.pack();
// Add Listeners
textField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
out.println(textField.getText());
textField.setText("");
}
});
}
/**
* Prompt for and return the address of the server.
*/
private String getServerAddress() {
return JOptionPane.showInputDialog(
frame,
"Enter IP Address of the Server:",
"Welcome to the Messager",
JOptionPane.QUESTION_MESSAGE);
}
/**
* Prompt for and return the desired screen name.
*/
private String getName() {
return JOptionPane.showInputDialog(
frame,
"Choose a screen name:",
"Screen name selection",
JOptionPane.PLAIN_MESSAGE);
}
/**
* Connects to the server then enters the processing loop.
*/
private void run() throws IOException {
// Make connection and initialize streams
String serverAddress = getServerAddress();
Socket socket = new Socket("86.190.97.107", 9001);
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
// Process all messages from server, according to the protocol.
while (true) {
String line = in.readLine();
if (line.startsWith("SUBMITNAME")) {
out.println(getName());
} else if (line.startsWith("NAMEACCEPTED")) {
textField.setEditable(true);
} else if (line.startsWith("MESSAGE")) {
messageArea.append(line.substring(8) + "\n");
}
}
}
/**
* Runs the client as an application with a closeable frame.
*/
public static void main(String[] args) throws Exception {
ChatClient client = new ChatClient();
client.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
client.frame.setVisible(true);
client.run();
}
}
Thanks for all of your answers i found out that the server needed to be hosted on a separate computer for the external IP to work.
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;
import javax.swing.*;
/* The code is able to run single client but not multiple client. When I run this program with my client class it is able to handle only one client. While I run multiple threads it lost its communication with the first thread. I don't know why. */
public class MultipleChatClient extends JFrame{
Vector<HandleAClient> clients = new Vector<HandleAClient>();
JButton btnSend = null;
JButton btnExit = null;
JTextArea taMessages = null;
JTextField tfInput = null;
BufferedReader br = null;
PrintWriter pw = null;
ServerSocket server = null;
Socket socket = null;
int clientNumber = 0;
public MultipleChatClient(){
this.Interface(); /* creates GUI */
try{
server = new ServerSocket(8900);
while(true){
socket = server.accept();
HandleAClient task = new HandleAClient(socket); /* add every client to vector */
clients.add(task);
new Thread(task).start();
}
}
catch(IOException ex){
ex.printStackTrace();
}
}
public class HandleAClient implements Runnable{ /* multithreaded class to handle multiclients */
private Socket socket;
public HandleAClient(Socket socket){
clientNumber++;
this.socket = socket;
}
public void run(){
try{
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
pw = new PrintWriter(socket.getOutputStream(), true);
while(true){
String line = br.readLine();
taMessages.append("Client Number " + clientNumber + " said: ");
taMessages.append(line + "\n");
}
}
catch(IOException ex){
ex.printStackTrace();
}
catch(Exception e){
taMessages.append("Connection Lost");
}
}
public void sendMessage() {
pw.println(tfInput.getText());
}
}
public void Interface(){ /* to build GUI */
setLayout(new BorderLayout());
btnSend = new JButton("Send");
btnExit = new JButton("Exit");
taMessages = new JTextArea();
taMessages.setRows(10);
taMessages.setColumns(50);
taMessages.setEditable(false);
tfInput = new JTextField(50);
JPanel but = new JPanel(new GridLayout(2,1,5,10));
but.add(btnSend);
but.add(btnExit);
JScrollPane sp = new JScrollPane(taMessages, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
add(sp,"Ce`enter code here`nter");
JPanel bp = new JPanel(new BorderLayout());
bp.add(tfInput, BorderLayout.CENTER);
bp.add(but, BorderLayout.EAST);
add(bp, BorderLayout.SOUTH);
btnSend.addActionListener(new buttonListner());
//btnSend.addKeyListener(new buttonListner());
btnExit.addActionListener(new buttonListner());
setSize(600,600);
setTitle("Server");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
//pack();
}
public class buttonListner implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == btnExit){
System.exit(1);
}
else{
taMessages.append("You Said: ");
taMessages.append(tfInput.getText() + "\n");
for(HandleAClient c: clients){
c.sendMessage();
}
tfInput.setText(null);
}
}
}
public static void main(String[] args) {
new MultipleChatClient();
}
}
You have to use Multi-threading. Create a new Thread for each client connected to the server.
I have already posted some of the samples in the same context.
Please have a look at below posts. It might help you to understand it.
Java Server with Multiclient communication.
Multiple clients access the server concurrently
Im making a chat program.
i got the client to server connection working but i cant get the server to send to all sockets. Since Im using ObjectOutputStream i cant use PrintWriter which was the way I did it before, Heres my code thanks for the help
Server
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Server {
public Server clients[] = new Server[50];
public static String user;
private static final int PORT = 4000;
private static HashSet<String> names = new HashSet<String>();
private static HashSet<PrintWriter> writers = new HashSet<>();
public static void main(String[] args) throws Exception{
System.out.println("The chatroom is running...");
ServerSocket listener = new ServerSocket(PORT);
try{
while(true){
new Handler(listener.accept()).start();
}
}
catch(Exception e){
System.err.println(e);
}
finally{
listener.close();
}
}
private static class Handler extends Thread{
private String name;
private Socket socket;
//private BufferedReader in;
//private PrintWriter out;
public ObjectOutputStream out;
public ObjectInputStream in;
public void send(Message msg) throws IOException{
out.writeObject(msg);
out.flush();
}
public void Announce(String type, String sender, String content){
Message msg = new Message(type, sender, content, "All");
}
public Handler(Socket socket){
this.socket = socket;
}
public void run(){
try {
out = new ObjectOutputStream(socket.getOutputStream());
out.flush();
in = (new ObjectInputStream(socket.getInputStream()));
out.writeObject(new Message("SUBMITNAME", "blank", "blank", "blank"));
while(true){
Message msg = (Message) in.readObject();
if(msg.sender == null){
return;
}
if(!names.contains(msg.sender)){
names.add(msg.sender);
System.out.println(names.toString());
System.out.println("The object is " + msg);
}
break;
}
while(true){
Message msg = (Message) in.readObject();
System.out.println(msg);
names.add(msg.sender);
System.out.println(names.toString());
break;
}
//out.writeObject(new Message("MESSAGE", "Server", "Welcome To the ChatRoom", "c"));
while(true){
Message msg = (Message) in.readObject();
if(msg.type.equals("MESSAGE")){
out.writeObject(new Message("MESSAGE", msg.sender, msg.content, "all"));
System.out.println(msg.sender + ": " + msg.content);
}
}
}
catch (Exception e) {
System.err.println(e);
}
finally{
try{
socket.close();
System.out.println("Socket has closed");
}
catch(IOException e){
System.err.println("Problem closing socket!");
}
}
}
}
}
Client
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.Socket;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.text.DefaultCaret;
import static javax.swing.text.DefaultCaret.ALWAYS_UPDATE;
public class Client implements Serializable{
//private BufferedReader in;
//private PrintWriter out;
ObjectOutputStream out;
ObjectInputStream in;
String name;
JFrame frame = new JFrame("Client Box");
JTextField textField = new JTextField(40);
JTextArea messageArea = new JTextArea(8,40);
JScrollPane scroll = new JScrollPane(messageArea);
ArrayList<String> list = new ArrayList();
public Client(){
textField.setEditable(false);
messageArea.setEditable(false);
messageArea.setWrapStyleWord(true);
messageArea.setLineWrap(true);
DefaultCaret caret = (DefaultCaret) messageArea.getCaret();
caret.setUpdatePolicy(ALWAYS_UPDATE);
//frame.setLayout(new BorderLayout());
frame.getContentPane().add(textField, BorderLayout.SOUTH);
frame.getContentPane().add(scroll, BorderLayout.CENTER);
frame.pack();
textField.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
try{
//Message msg = new Message("MESSAGE", name, textField.getText(), "all");
//out.writeObject(msg);
sendAll("MESSAGE", name, textField.getText());
textField.setText("");
}catch(IOException ex){System.err.println(ex.printStackTrace()};
}
});
}
public void sendAll(String type, String sender, String content) throws IOException{
Message msg = (new Message(type, sender, content, "all"));
out.writeObject(msg);
out.flush();
}
private String getName(){
return JOptionPane.showInputDialog(frame, "Your Screen Name?", "Please Enter Screen Name: "
, JOptionPane.PLAIN_MESSAGE);
}
private String getMessage(){
return JOptionPane.showInputDialog(frame, "Your message?", "Please Enter Screen Name: "
, JOptionPane.PLAIN_MESSAGE);
}
private void run() throws IOException, ClassNotFoundException{
//String address = getServerAddress();
Socket socket = new Socket("localhost", 4000);
in = (new ObjectInputStream(socket.getInputStream()));
out = new ObjectOutputStream(socket.getOutputStream());
Message temp = (Message) in.readObject();
if(temp.type.equals("SUBMITNAME")){
textField.setEditable(true);
name = getName();
sendAll(name, "a", " b");
}
while(true){
Message msg = (Message) in.readObject();
messageArea.append(msg.sender + ": " + msg.content + "\n");
}
}
public static void main(String[] args) throws ClassNotFoundException{
Client client = new Client();
client.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
client.frame.setLocationRelativeTo(null);
client.frame.setVisible(true);
try {
try {
client.run();
} catch (IOException ex) {
Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
}
}
}