Broadcast client message to all clients in a chatroom Java - java

So I've been making a chatroom based off a single server, where clients can connect and talk in the chatroom. At the moment each client can speak to the server and the server returns what the client has said. But I've been struggling to broadcast a single client message to all clients.
I stored all socket connections in an ArrayList and then created a for loop to iterate through all the connections to echo a single message to all the connected clients. Unfortunately my code is not working and I can't understand why. Here's my code:
Handler code:
public class Handler implements Runnable {
private Socket client;
String message = "";
public Handler(Socket client){
this.client = client;
}
#Override
public void run() {
try{
try{
ChatClient CCG = new ChatClient();
Scanner INPUT = new Scanner(client.getInputStream()); //input data from the server
PrintWriter OUT = new PrintWriter(client.getOutputStream()); //output data from the server
while(true){
if(!INPUT.hasNextLine()){ //if nothings there, end it
return;
}
message = INPUT.nextLine(); //get input
System.out.println("Client HANDLER said: "+ message);
//echo out what the client says to all the users
for(int i=1; i<= ChatServer.ConnectionArray.size(); i++){
Socket TEMP_SOCK = (Socket) ChatServer.ConnectionArray.get(i-1);
PrintWriter TEMP_OUT = new PrintWriter(TEMP_SOCK.getOutputStream());
TEMP_OUT.println(message);
TEMP_OUT.flush();
System.out.println("Sent to: " + TEMP_SOCK.getLocalAddress().getHostName()); //displyed in the console
}
}
}finally{
client.close();
}
}catch(Exception X){
X.printStackTrace();
}
}
}
EDIT: Changed client.getOutputStream() to TEMP_SOCK.getOutputStream() but still no luck :/
Server code:
public class ChatServer {
public static ServerSocket server;
public static boolean ServerOn=true;
public static ArrayList<Socket> ConnectionArray = new ArrayList<Socket>(); //holds all the connections so messages can be echoed to all the other users
public static ArrayList<String> CurrentUsers = new ArrayList<String>(); //current users
public static void main(String[] args){
//ExecutorService executor = Executors.newFixedThreadPool(30); //number of clients allowed to join the server
try {
server = new ServerSocket(14001);
System.out.println("Server started!");
System.out.println("Waiting for clients to connect...");
while(true){
try {
//ChatClient chatClient = new ChatClient();
Socket client = server.accept();
ConnectionArray.add(client); //add socket to connection array and allows multiple users to enter server
System.out.println(ConnectionArray);
//CurrentUsers.add(chatClient.user);
//System.out.println("Current users: "+CurrentUsers);
System.out.println("Client connected from: " + client.getLocalAddress().getHostName()); //gets their ip address and local host name
Thread thread = new Thread(new Handler(client));
thread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Client Code:
public class ChatClient extends javax.swing.JFrame {
Socket sock;
String message;
int port = 14001;
PrintWriter write;
BufferedReader read;
String user;
ArrayList<String> usersOnline = new ArrayList();
InputStreamReader streamreader;
boolean userConnected = false;
public ChatClient() {
initComponents();
}
/*public class Incoming implements Runnable{
public void run(){
try{
sock = new Socket("localhost",14001);
write = new PrintWriter(out);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}*/
public void addUser(){
onlineUsersTextArea.append(user+" \n");
usersOnline.add(user);
System.out.println(usersOnline);
}
/*public void Send(){
String bye = (user + ": :Disconnect");
try{
write.println(bye);
write.flush();
}catch(Exception ex){
chatTextArea.append("Could not send disconnect message. \n");
}
}*/
public void userDisconnected(){
chatTextArea.append(user + " has disconnected.\n");
}
public void Disconnect(){
try{
chatTextArea.append("Disconnected.\n"); // Notify user that they have disconnected
write.flush();
sock.close(); // Closes the socket
System.out.println(user + " has disconnected.");
}catch(Exception e){
chatTextArea.append("Failure to disconnect.\n");
}
userConnected = false;
onlineUsersTextArea.setText(""); // Remove name from online users
usernameInputField.setEditable(true); // Allows a username to be created
}
private void connectButtonActionPerformed(java.awt.event.ActionEvent evt) {
if(userConnected == false){
user = usernameInputField.getText();
usernameInputField.setEditable(false);
try{
sock = new Socket("localhost", port);
InputStreamReader sReader = new InputStreamReader(sock.getInputStream());
write = new PrintWriter(sock.getOutputStream());
read = new BufferedReader(sReader);
addUser();
chatTextArea.append(user + " has connected. \n");
write.println(user+" has connected."); // Display username of client when connection is established
write.flush(); // Flushes the stream
userConnected = true;
} catch (IOException ex) {
chatTextArea.append("Failed to connect.\n");
usernameInputField.setEditable(true);
ex.printStackTrace();
}
}else if(userConnected == true){
chatTextArea.append("You are already connected. \n");
}
}
private void disconnectButtonActionPerformed(java.awt.event.ActionEvent evt) {
Disconnect();
userDisconnected();
}
private void sendButtonActionPerformed(java.awt.event.ActionEvent evt) {
String nothing = "";
if((userInputTextArea.getText()).equals(nothing)){
userInputTextArea.setText("");
userInputTextArea.requestFocus();
}else{
try{
chatTextArea.append(user + ": " + userInputTextArea.getText()+" \n");
write.println(user + ": " + userInputTextArea.getText());
write.flush();
}catch(Exception ex){
chatTextArea.append("Message failed to send. \n");
}
userInputTextArea.setText("");
userInputTextArea.requestFocus();
}
userInputTextArea.setText("");
userInputTextArea.requestFocus();
}
private void usernameInputFieldActionPerformed(java.awt.event.ActionEvent evt) {
}
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new ChatClient().setVisible(true);
}
});
}
}
My for loop is in the Handler class. I'm not understanding why the message isn't being sent out to the clients. The TEMP_SOCK (temporary socket) should work (I think) but the server only receives the messages but doesn't echo them.
Any help on how to go about this would be really appreciated! Thank you :)

PrintWriter TEMP_OUT = new PrintWriter(client.getOutputStream()); means you're always sending to the same client, you should use PrintWriter TEMP_OUT = new PrintWriter(TEMP_SOCK.getOutputStream());

Related

Java Sockets - How can I send messages to multiple threads?

I made a Chat Application (Server/Client) using Java. Note: The server is ran as its own jar file and each client is ran as its own jar file.
Each client is on their own thread.
Whenever I send messages to the server, each client receives the message, however when I send messages from the client, only the server receives the message. When the client sends a message, I want all connected clients and the server to receive the message so all of the clients can communicate together and with the server as well.
I've looked at multiple posts and videos about this, but most were too confusing for me to understand.
Could someone please help me understand how I can send messages between threads? Thanks!
-- My Code --
Client:
public Client(User user, String address, int port) {
try {
socket = new Socket(address, port);
ClientApplicationUI app = new ClientApplicationUI();
app.setTitle("Chat Application - " + user.getUsername());
app.setVisible(true);
ServerConnection connection = new ServerConnection(socket, app);
output = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
new Thread(connection).start();
app.getButton().addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (app.getTextField().getText() != null && app.getTextField().getText().length() > 0) {
String message = MessageUtil.getMessage(Message.LOGGER_PREFIX) + " <" + user.getUsername() + "> " + app.getTextField().getText() + "\n";
try {
output.writeUTF(message);
output.flush();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
});
} catch (UnknownHostException e) {
System.out.println(e);
System.out.println("Could not connect! Reason: " + e);
} catch (IOException e) {
System.out.println("Could not connect! Reason: " + e);
}
}
ServerConnection
public class ServerConnection implements Runnable {
#SuppressWarnings("unused")
private Socket socket;
private DataInputStream in;
private ClientApplicationUI app;
public ServerConnection(Socket socket, ClientApplicationUI app) throws IOException {
this.socket = socket;
this.app = app;
in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
}
#Override
public void run() {
while (true) {
String message;
try {
message = in.readUTF();
app.logMessage(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Server
public class Server {
private Socket socket = null;
private ServerSocket server = null;
private ExecutorService pool = Executors.newFixedThreadPool(4);
public Server (int port) {
try {
ApplicationUI app = new ApplicationUI();
app.setVisible(true);
server = new ServerSocket(port);
app.logMessage(MessageUtil.getMessage(Message.LOGGER_PREFIX) + " " + MessageUtil.getMessage(Message.INFO) + " Server started!\n");
app.logMessage(MessageUtil.getMessage(Message.LOGGER_PREFIX) + " " + MessageUtil.getMessage(Message.INFO) + " Waiting for new connections...\n");
while (true) {
socket = server.accept();
ConnectionHandler clientThread = new ConnectionHandler(socket, app);
app.logMessage(MessageUtil.getMessage(Message.LOGGER_PREFIX) + " " + MessageUtil.getMessage(Message.INFO) + " A new client has been accepted!\n");
pool.execute(clientThread);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Server server = new Server(58139);
}
}
ConnectionHandler
public class ConnectionHandler implements Runnable {
private Socket client;
private ApplicationUI app;
private DataInputStream in;
private DataOutputStream out;
public ConnectionHandler(Socket client, ApplicationUI app) throws IOException {
this.client = client;
this.app = app;
in = new DataInputStream(new BufferedInputStream(client.getInputStream()));
out = new DataOutputStream(new BufferedOutputStream(client.getOutputStream()));
}
#Override
public void run() {
try {
app.getButton().addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (app.getTextField().getText() != null && app.getTextField().getText().length() > 0) {
String message = MessageUtil.getMessage(Message.LOGGER_PREFIX) + " <Server> " + app.getTextField().getText() + "\n";
try {
sendMessage(message);
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
});
String message = "";
while (!message.equals("/stop")) {
message = in.readUTF();
app.logMessage(message);
}
} catch (IOException e) {
System.err.println("IO exception in connection handler!");
System.err.println(e.getStackTrace());
} finally {
try {
out.close();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void sendMessage(String message) throws IOException {
out.writeUTF(message);
out.flush();
}
}
You need to understand, how sockets work. They are always Client and Server.
There are two ways you could achieve what you want:
First solution:
Send the message which is meant for all clients to the server and let the server distribute the message to all the other clients. The server will need to keep track of the already connected clients, i.e. store their Socket.
Second solution: (which totally is not advisable)
If you want to send a message to a client of a network without haveing the actual server involved, you will need that client to act as a server, or the other way around. This means that every client will actually need to listen to every other client, instead of only the server.
You should definitely go with the first solution!

Java Threaded Server Client Messaging Application

I'm trying to make a threaded server client messaging application in java. I'm having trouble sending a message that a client sent to every other client connected to the server. I added all connected threads to an array list so when a message is sent I can iterate over the list and send it to all the clients but this doesn't seem to be working. What am I doing wrong here?
When one client is connected it works perfectly the server echos everything the client says. When two clients are connected only the client that sent the message gets the message. If that same client though send another message the server seems to get hung up and no messages get echoed.
Threaded Server Code
import java.io.*;
import java.net.*;
import java.util.*;
public class ThreadedSever
{
private static final int port=5000;
ArrayList<ServerThread> clientList = new ArrayList<ServerThread>();
//Threaded Server
public ThreadedSever(){
System.out.println("A multi-threaded server has started...");
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(port);
}catch(Exception e){
System.out.println("Could not create a server socket: " + e);
}
//Chat with the client until breaks connection or says bye
try{
while(true){
System.out.println("Waiting for client communication");
Socket currentSocket = serverSocket.accept();
//Create a new thread to deal with this connection
clientList.add(new ServerThread(currentSocket));
System.out.println(clientList);
}
}catch(Exception e){
System.out.println("Fatal Server Error!");
}
}
//Inner class to handle individual commincation
private class ServerThread extends Thread{
//Possible add name to then get private messages
private Socket sock;
private DataInputStream in = null;
private DataOutputStream out = null;
public ServerThread(Socket sock){
try{
this.sock = sock;
in = new DataInputStream(this.sock.getInputStream());
out = new DataOutputStream(this.sock.getOutputStream());
System.out.print("New client connection established");
out.writeUTF("Type bye to exit, otherwise, prepare to be echoed");
start();
}catch(Exception e){
System.out.println("Oops");
}
}
public void run(){
try{
String what = new String("");
while(!what.toLowerCase().equals("bye")){
what = in.readUTF();
echoMessage(what);
}
}catch(Exception e){
System.out.println("Connection to current client has been broken");
}
finally{
try{
sock.close();
}catch(Exception e){
System.out.println("Error socket could not be closed");
}
}
}
public void echoMessage(String what){
try{
for (ServerThread Thread: clientList) {
in = Thread.in;
out = Thread.out;
System.out.println("Client told me: " + what);
out.writeUTF(what);
}
}catch(Exception e){
}
}
}
public static void main(){
new ThreadedSever();
}
}
Client Code
import java.io.*;
import java.net.*;
public class simpleClient
{
private static final int port= 5000;
private static String server = "localhost";
private static Socket socket = null;
private static DataInputStream input = null;
private static DataOutputStream output = null;
private static InputStreamReader inReader = null;
private static BufferedReader stdin = null;
public static void main(){
try{
socket = new Socket(server, port);
}catch(UnknownHostException e){
System.err.println("Unknow IP address for server");
System.exit(-1);
}
catch(IOException e){
System.err.println("No server found at specified port");
System.exit(-1);
}
catch(Exception e){
System.err.println("Something happened!");
System.exit(-1);
}
try{
input = new DataInputStream(socket.getInputStream());
output = new DataOutputStream(socket.getOutputStream());
inReader = new InputStreamReader(System.in);
stdin = new BufferedReader(inReader);
String what = new String("");
String response;
while(!what.toLowerCase().equals("bye")){
// Expect something from the server and output it when it arrives
response = input.readUTF();
System.out.println("Server said \"" + response + "\"");
//Read a line from the user and send it to the server
what = stdin.readLine();
output.writeUTF(what);
}
}
catch(IOException e){
System.err.println("Broken connection with server");
System.exit(-1);
}
}
}

Android - PC usb connection - do it without wifi

I wanted to ask how to change following code, which needs USB connection and WIFI to work... (and I don't know why wifi...), to code, which needs only USB cable and NO WIFI!, because I don't want to be dependent on wifi...
Could you please help me? Some changes or additions in code? Thanks.
Code for Android:
private final Runnable connectToServer = new Thread()
{
#Override
public void run()
{
try
{// Get the server address from a dialog box.
String serverAddress = "192.168.0.23";
// Make connection and initialize streams
Socket socket = new Socket(serverAddress, 38300);
in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
// Consume the initial welcoming messages from the server
for (int i = 0; i < 3; i++) {
System.out.println(in.readLine());
}
solveCube();
} catch (IOException e) {
e.printStackTrace();
}
}
};
private final Runnable initializeConnection = new Thread()
{
#Override
public void run()
{
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(generateCubeString());
out.println(generateCubeString());
String response ="";
try {
response = in.readLine();
if (response == null || response.equals("")) {
System.exit(0);
}
} catch (IOException ex) {
}
if (response.contains("Error")) {
} else {
solveCubeAnimate(response);
}
System.out.println(response);
final String finalResponse = response;
runOnUiThread(new Runnable() {
#Override
public void run() {
textView.setText(finalResponse);
}
});
}
};
Code for PC
private static class Capitalizer extends Thread {
private Socket socket;
private int clientNumber;
public Capitalizer(Socket socket, int clientNumber) {
this.socket = socket;
this.clientNumber = clientNumber;
log("New connection with client# " + clientNumber + " at " + socket);
}
/**
* Services this thread's client by first sending the
* client a welcome message then repeatedly reading strings
* and sending back the capitalized version of the string.
*/
public void run() {
try {
// Decorate the streams so we can send characters
// and not just bytes. Ensure output is flushed
// after every newline.
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
// Send a welcome message to the client.
out.println("Hello, you are client #" + clientNumber + ".");
out.println("Enter a line with only a period to quit\n");
// Get messages from the client, line by line; return them
// capitalized
while (true) {
String input = in.readLine();
if (input == null || input.equals(".")) {
break;
}
out.println(solveCube(input));
}
} catch (IOException e) {
log("Error handling client# " + clientNumber + ": " + e);
} finally {
try {
socket.close();
} catch (IOException e) {
log("Couldn't close a socket, what's going on?");
}
log("Connection with client# " + clientNumber + " closed");
}
}
/**
* Logs a simple message. In this case we just write the
* message to the server applications standard output.
*/
private void log(String message) {
System.out.println(message);
}
}
private static class Connecter extends Thread {
/**
* Services this thread's client by first sending the
* client a welcome message then repeatedly reading strings
* and sending back the capitalized version of the string.
*/
public void run() {
try {
System.out.println("The capitalization server is running.");
int clientNumber = 0;
ServerSocket listener = new ServerSocket(38300);
try {
while (true) {
new Capitalizer(listener.accept(), clientNumber++).start();
}
} finally {
listener.close();
}
} catch (IOException ex) {
Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

Chat Program: Client to Client Chat

Currently I'm working on this mini chat program in Java where multiple users should be able to log into the chat program and chat. Right now what my program does is log in users (Clients) to the Server, and what ever they say gets echoed back by the Server. What I want to do is be able to send a request to chat with another client directly.
My idea was to create a Hash map that holds the username of the client and its socket. When a client requests to chat with another client it looks for that user's username in the HashMap and if the other client agrees to chat then it connects the sockets.
I'm not sure how to implement this and also my program only takes one input from the user and returns it from the Server and after that it stops I have no idea why. I've been trying to get this working for a while now, starting to give me headaches.
Here's the code:
Client Class:
package source;
import java.io.*;
import java.util.*;
import java.net.*;
public class Client implements Runnable {
private Socket socket;
private DataOutputStream dout;
private DataInputStream din;
// Constructor
public Client() {
// Code
}
public Client(String host, int port) {
try {
socket = new Socket(host, port);
System.out.println("connected to " + socket);
din = new DataInputStream(socket.getInputStream());
dout = new DataOutputStream(socket.getOutputStream());
new Thread(this).start();
} catch (IOException ie) {
System.out.println(ie);
}
}
private void processMessage(String message) {
try {
dout.writeUTF(message);
} catch (IOException ie) {
System.out.println(ie);
}
}
public void run() {
try {
while (true) {
String message = din.readUTF();
System.out.println(message);
}
} catch (IOException ie) {
System.out.println(ie);
}
}
public static void main(String[] args) throws IOException {
while (true) {
String prompt;
Scanner clientPrompt = new Scanner(System.in);
System.out.println("client> ");
prompt = clientPrompt.next();
if (prompt.equals("Emmanuel"))
System.out.println("God With Us");
else if (prompt.equals("goOnline")) {
// Enter a host name
// Enter a portNumber
// Enter a userName
String h, p, u;
System.out.println("Enter hostname: ");
h = clientPrompt.next();
System.out.println("Enter portNumber: ");
p = clientPrompt.next();
System.out.println("Enter userName: ");
u = clientPrompt.next();
goOnline(h, p, u);
} else if (prompt.equals("Exit")) {
clientPrompt.close();
System.exit(1);
} else {
System.out.println("Invalid Input, Try Again");
}
}
}
public static void goOnline(String host, String port, String userName) {
int portNumber = Integer.parseInt(port);
Client c = new Client(host, portNumber);
c.processMessage("Username: " + userName);
String prompt;
Scanner clientPrompt = new Scanner(System.in);
while (true) {
prompt = clientPrompt.next();
c.processMessage(prompt);
c.run();
if (prompt.equals("Exit")) {
System.out.println("Bye Bye");
clientPrompt.close();
}
}
}
}
Server Class:
package source;
import java.io.*;
import java.net.*;
import java.util.*;
public class Server { // The ServerSocket we'll use for accepting new
// connections
private ServerSocket ss;
private HashMap<String, Socket> userInfo = new HashMap<String, Socket>();
// A mapping from sockets to DataOutputStreams.
private Hashtable<Socket, DataOutputStream> outputStreams = new Hashtable<Socket, DataOutputStream>();
// Constructor and while-accept loop all in one.
public Server(int port) throws IOException {
// All we have to do is listen
listen(port);
}
private void listen(int port) throws IOException {
// ServerSocket
ss = new ServerSocket(port);
System.out.println("Listening on " + ss);
while (true) {
Socket s = ss.accept();
System.out.println("Connection from " + s);
DataOutputStream dout = new DataOutputStream(s.getOutputStream());
DataOutputStream userInfo = new DataOutputStream(s.getOutputStream());
outputStreams.put(s, dout);
outputStreams.put(s, userInfo);
new ServerThread(this, s);
}
}
Enumeration<DataOutputStream> getOutputStreams() {
return outputStreams.elements();
}
void sendToAll(String message) {
for (Enumeration<DataOutputStream> e = getOutputStreams(); e.hasMoreElements();) {
// Output Stream
DataOutputStream dout = (DataOutputStream) e.nextElement();
// Send Message
try {
dout.writeUTF(message);
} catch (IOException ie) {
System.out.println(ie);
}
}
}
// Remove socket,
void removeConnection(Socket s) {
// Synchronize
synchronized (outputStreams) {
// Tell the world
System.out.println("Removing connection to " + s);
// Remove it from hashtable
outputStreams.remove(s);
try {
s.close();
} catch (IOException ie) {
System.out.println("Error closing " + s);
ie.printStackTrace();
}
}
}
void addInfo(String user, Socket s) {
userInfo.put(user, s);
}
// Main
static public void main(String args[]) throws Exception {
// Get port
int port = Integer.parseInt(args[0]);
// Create Server object
new Server(port);
}
}
ServerThread:
package source;
import java.io.*;
import java.util.*;
import java.net.*;
public class ServerThread extends Thread { // The Server that spawned us
private Server server;
private Socket socket;
public ServerThread(Server server, Socket socket) {
this.server = server;
this.socket = socket;
start();
}
public void run() {
try {
DataInputStream din = new DataInputStream(socket.getInputStream());
while (true) {
String message = din.readUTF();
StringTokenizer stt = new StringTokenizer(message, " ");
while (stt.hasMoreTokens()) {
String token = stt.nextToken();
if (token.equals("Username:")) {
String username = stt.nextToken();
server.addInfo(username, socket);
}
}
System.out.println("Sending " + message);
server.sendToAll(message);
if (message.equals("Exit")) {
System.out.println("Bye Bye");
server.removeConnection(socket);
System.exit(1);
}
}
} catch (EOFException ie) {
} catch (IOException ie) {
ie.printStackTrace();
} finally {
server.removeConnection(socket);
}
}
}
my program only takes one input from the user and returns it from the Server and after that it stops I have no idea why?
Just do one change as mentioned below at client side to resolve above issue.
public void run() {
try {
// while (true) { // remove an infinite loop that will block
// the client thread to accept next message
String message = din.readUTF();
System.out.println(message);
// }
} catch (IOException ie) {
System.out.println(ie);
}
}
Doubt: (client side)
You have started a thread then why are you calling run() method directly.

Server Send Out message from one client to all Clients conneted. JAVA

I am writing a Server/Client chat where basically Multiple Clients connected to One Server. One client send a message to server Then all other Clients will get the same message. For example: Client A, B, C Connected to A same Server. Client A send Message To Server, Server then will send the same message to client B and C but exclude Client A.
I'm stuck at part where Server send out the message to all other clients.
Below is the code, I'm just a Java beginner so any help with the code will be much appreciate.
ServerSide
public class ServerP2P extends Thread{
private ServerSocket server = null;
private Socket clientSocket = null;
private ArrayList<ServerThread> clientThreadList = new ArrayList<>();
private int maxClient = 4;
private int port = 9990;
boolean listening = true;
public ServerP2P(){
try{
server = new ServerSocket(port);
}catch(IOException e){
e.printStackTrace();
return;
}
System.out.println("Server with Port "+port+" is Up and Running");
}
public void run(){
System.out.println("Room Chat Is Up");
while(listening){
for(int i = 0;i<clientThreadList.size();i++){
if(!clientThreadList.get(i).getConneection()){
System.out.println(clientThreadList.get(i)+" is removing from server because there is no conntection");
clientThreadList.remove(i);
}
}
try{
clientSocket = server.accept();
}catch(Exception e){
e.printStackTrace();
}
System.out.println("User with IP "+clientSocket.getInetAddress()+" Has Connected to Server");
clientThreadList.add(new ServerThread(clientSocket));
try{
Thread.sleep(200);
}catch(Exception e){
e.printStackTrace();
}
}
}
public ArrayList<ServerThread> listOFClient(){
return clientThreadList;
}
public static void main(String[] args){
ServerP2P server = new ServerP2P();
server.start();
}
}
ServerThread
public class ServerThread{
private Socket clientSocket;
private boolean connected;
private Incomming incommingData;
String msg = null;
private class Incomming extends Thread{
private DataInputStream input;
public void run(){
try{
input = new DataInputStream(clientSocket.getInputStream());
}catch(IOException e){
e.printStackTrace();
return;
}
System.out.println("User with IP "+clientSocket.getInetAddress()+" has connected");
while(true){
try{
Thread.sleep(200);
int msgSize = input.readInt();
byte[] msgByte = new byte[msgSize];
for(int i = 0; i < msgSize ; i++){
msgByte[i] = input.readByte();
}
msg = new String(msgByte);
System.out.println(msg);
}catch(Exception e){
e.printStackTrace();
}
}
}
}
public ServerThread(Socket newClientSocket){
this.clientSocket = newClientSocket;
connected = true;
incommingData = new Incomming();
incommingData.start();
}
public boolean getConneection(){
return connected;
}
public void closeConnection(){
try{
connected = false;
clientSocket.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
ClientSide
public class ClientP2P{
private Socket serverSocket = null;;
private DataOutputStream output = null;
BufferedReader reader = new BufferedReader(new InputStreamReader(
System.in));
public static void main(String[] args) {
ClientP2P client = new ClientP2P();
client.startConnect();;
}
public void startConnect(){
int port = 9990;
try {
serverSocket = new Socket("localhost", port);
System.out.println(serverSocket.isBound());
output = new DataOutputStream(serverSocket.getOutputStream());
System.out.println("Please Enter Your name: ");
String nameClient = reader.readLine();
output.writeInt(nameClient.length());
output.writeBytes(nameClient);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("You Are Connected");
System.out.println("Chat Can Start");
sendText();
}
public void sendText(){
try {
while (true) {
System.out.println("Type Message: ");
String msg = reader.readLine();
output.writeInt(msg.length());
output.writeBytes(msg);
System.out.println("Message sent");
recivedText();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void recivedText(){
try{
DataInputStream input = new DataInputStream(serverSocket.getInputStream());
int textSize = 0;
while(input.available() != 0){
byte[] byteString = new byte[textSize];
for(int i = 0; i < textSize;i++){
byteString[i] = input.readByte();
}
String txtServer = new String(byteString);
System.out.println(txtServer);
textSize = 0;
}
sendText();
}catch(Exception e){
e.printStackTrace();
}
}
}
Thanks For Your Time Guys.
Your ServerThread receives the messages and you want to send them to all other clients. One way you could achieve is to have the clients register themselves with the Server (this would help in the server not knowing the clients when it starts, which ideally should be the case). In your ServerThread, get a list of available clients from the server and loop through them and send the message to each one of them.
Use ObserverDesign pattern to hold the list of all your buddy/user to whom you wish to send message. Use HashMap to maintain a list of all the observer and its socket. Once the message is received, you retrieve the sockets of each user and write the same message on each socket.

Categories

Resources