Chat Program: Client to Server Connectivity Issue - java

Project Summary
Goal: A simple application that connects a client to a server hosted on one computer and allows that client from another computer to send chat messages to everyone on that specified server.
Class ClientWindow: Runs an application that prompts the user to enter in a server ID and port. Once entered, it starts the chat program.
Problem:
For some reason unknown to me, the chat program ONLY works when connecting to a server that you've created on your own computer. Other clients from other computers cannot connect to that server.
Possible reasons for problem:
I might have incorrectly constructed the server's receiving/sending sockets
I might have incorrectly constructed the client's receiving/sending sockets
Something is getting wonky in the packets being sent between client and server
Somehow IP addresses for the sockets are being defined incorrectly
Here is the code for the chat program.
Start server
This class starts the server on the specified port. (12348 in this instance)
package server;
public class ChatServer {
public static void main(String[] args) {
// TODO Auto-generated method stub
Server.start(12348);
}
}
Server
This is the class that creates the server and listens for client connections and messages.
package server;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.ArrayList;
public class Server {
private static DatagramSocket socket;
private static boolean running;
private static int ClientID; // Ensures that no two users have the same client ID
private static ArrayList<ClientInfo> clients = new ArrayList<ClientInfo>();
public static void start(int port) {
try {
socket = new DatagramSocket(port);
System.out.println("Application Starting...");
running = true;
listen();
System.out.println("Server started on port: " + port);
} catch (Exception e) {
System.out.println("Failed somewhere");
e.printStackTrace();
}
}
private static void broadcast(String message) {
for (ClientInfo info : clients) {
send(message, info.getAddress(), info.getPort());
}
}
private static void send(String message, InetAddress address, int port) {
try {
message += "\\e";
byte[] data = message.getBytes();
DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
socket.send(packet);
System.out.println("Sent message to," + address.getHostAddress() + ":" + port);
} catch (Exception e) {
e.printStackTrace();
}
}
private static void listen() {
Thread listenThread = new Thread("ChatProgram Listener Thread") {
public void run() {
try {
while(running) {
byte[] data = new byte[1024];
DatagramPacket packet = new DatagramPacket(data, data.length);
socket.receive(packet);
String message = new String(data);
//Identify where the end of the message is
message = message.substring(0, message.indexOf("\\e"));
//Manage message
if(!isCommand(message, packet)) {
broadcast(message);
}
}
} catch(Exception e){
e.printStackTrace();
}
}
}; listenThread.start();
}
/*
* SERVER COMMAND LIST
* \con:[name] -> Connects client to server
* \dis:[id] -> Disconnects client from server
*
*
*
*/
private static boolean isCommand(String message, DatagramPacket packet) {
if (message.startsWith("\\con:")) {
// RUN CONNECTION CODE
String name = message.substring(message.indexOf(":") + 1);
clients.add(new ClientInfo(name, ClientID++, packet.getAddress(), packet.getPort()));
broadcast("User " + name + " Connected!");
return true;
}
if (message.startsWith("\\dis:")) {
// RUN DISCONNECTION CODE
return true;
}
return false;
}
public static void stop() {
running = false;
}
}
Start Client
Starts the client application.
package client;
import java.awt.EventQueue;
import java.awt.Frame;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTextField;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.awt.event.ActionEvent;
public class ClientWindow {
private JFrame frmChatProgram;
private JTextField textField;
private static JTextArea textArea = new JTextArea();
private Client client;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
ClientWindow window = new ClientWindow();
window.frmChatProgram.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public ClientWindow() throws UnknownHostException {
initialize();
String name = JOptionPane.showInputDialog("Enter name:");
String servIp = JOptionPane.showInputDialog("Enter server IP address:");
String port = JOptionPane.showInputDialog("Enter server port:");
int parsedPort = Integer.parseInt(port);
//InetAddress inetAddress = InetAddress.getLocalHost();
client = new Client(name, servIp, parsedPort);
}
private void initialize() {
frmChatProgram = new JFrame();
frmChatProgram.setResizable(false);
frmChatProgram.setTitle("Chat Program");
frmChatProgram.setBounds(100, 100, 620, 446);
frmChatProgram.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmChatProgram.setBackground(Color.WHITE);
frmChatProgram.getContentPane().setBackground(Color.DARK_GRAY);
frmChatProgram.getContentPane().setLayout(new BorderLayout(0, 0));
textArea.setForeground(Color.WHITE);
textArea.setBackground(Color.DARK_GRAY);
JScrollPane scrollPane = new JScrollPane(textArea);
frmChatProgram.getContentPane().add(scrollPane, BorderLayout.CENTER);
JPanel panel = new JPanel();
panel.setBackground(Color.GRAY);
frmChatProgram.getContentPane().add(panel, BorderLayout.SOUTH);
panel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
textField = new JTextField();
textField.setBackground(Color.WHITE);
panel.add(textField);
textField.setColumns(40);
JButton btnNewButton = new JButton("Send");
btnNewButton.addActionListener(e ->{
if (!textField.getText().equals("")) {
client.send(textField.getText());
textField.setText("");
}
});
panel.add(btnNewButton);
frmChatProgram.setLocationRelativeTo(null);
}
public static void printToConsole(String message) {
textArea.setText(textArea.getText() + message + "\n");
}
}
Client
Creates a client connection and listener for that client
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import server.ClientInfo;
public class Client {
private DatagramSocket socket;
private InetAddress address;
private int port;
private boolean running;
private String name;
public Client(String name, String address, int port) {
try {
this.name = name;
this.address = InetAddress.getByName(address);
this.port = port;
socket = new DatagramSocket();
socket.connect(this.address, port);
running = true;
listen();
send("\\con:" + name);
} catch (Exception e) {
e.printStackTrace();
}
}
public void send(String message) {
try {
if (!message.startsWith("\\")) {
message = name+": "+message;
}
message += "\\e";
byte[] data = message.getBytes();
DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
socket.send(packet);
System.out.println("Sent message to," + address.getHostAddress() + ":" + port);
} catch (Exception e) {
e.printStackTrace();
}
}
private void listen() {
Thread listenThread = new Thread("ChatProgram Listener Thread") {
public void run() {
try {
while (running) {
byte[] data = new byte[1024];
DatagramPacket packet = new DatagramPacket(data, data.length);
socket.receive(packet);
String message = new String(data);
// Identify where the end of the message is
message = message.substring(0, message.indexOf("\\e"));
// Manage message
if (!isCommand(message, packet)) {
ClientWindow.printToConsole(message);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}; listenThread.start();
}
private static boolean isCommand(String message, DatagramPacket packet) {
if (message.startsWith("\\con:")) {
// RUN CONNECTION CODE
return true;
}
if (message.startsWith("\\dis:")) {
// RUN DISCONNECTION CODE
return true;
}
return false;
}
}

I assume that you are asking about the possible reasons that your code is not be working:
1) I might have incorrectly constructed the server's receiving/sending sockets.
That is possible. You should be able to tell that by using a debugger to examine the packets on the server side.
2) I might have incorrectly constructed the client's receiving/sending sockets
Ditto ...
3) Something is getting wonky in the packets being sent between client and server
This is the most likely:
It could be a packet-level routing problem ... though that is likely to have broader effects.
It could be firewall issue
It could be an MTU issue
It could even be a broken switch, etc.
4) Somehow IP addresses for the sockets are being defined incorrectly
That is possible.
There are various things you could do to diagnose / eliminate the various possibilities. But this is not really a StackOverflow problem.

Related

How to handle multiple streams from a lobby server to clients

So, I'm having an issue with a project of mine. I'm writing a multiplayer lobby system which will enable multiple users to join a lobby, readying themselves by pressing a key. The issue that I'm facing is when two players is readying themselves, the lobby is only printing out a message for the last player who readied themselves. The system is built up in the following way.
Main Server
package master;
import java.net.*;
import java.io.*;
import java.util.*;
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
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 main.Lobby;
public class MainServer {
public static final int PORT = 4444;
public static final String HOST = "localhost";
public ArrayList<Lobby> serverList = new ArrayList<>();
public static void main(String[] args) throws IOException, ClassNotFoundException {
new MainServer().runServer();
}
public void runServer() throws IOException, ClassNotFoundException {
// Creating the server
ServerSocket serverSocket = new ServerSocket(PORT);
System.out.println("Main Server initiated.");
while (true) {
Socket socket = serverSocket.accept();
try {
// Establishing the connection to the Lobby server and then adding it to its list
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
objectOutputStream.writeObject("Server created successfully.");
Lobby s = (Lobby) objectInputStream.readObject();
this.serverList.add(s);
System.out.println("Server \"" + s.name + "\" added to game list.");
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
The lobby
package main;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.Semaphore;
import master.MainServer;
/**
* The Class Server.
*/
public class Lobby implements Serializable {
private static final long serialVersionUID = -21654L;
public static final int PORT = 4445;
public static final int MAX_USERS = 5000;
public static final String HOST = "localhost";
public String name = "Lobby Server";
public int clientNumber;
public int playerNumberReady = 0;
public boolean allPlayersReady = false;
public boolean OddurIsNice = false;
public static void main(String[] args) throws IOException, ClassNotFoundException {
Lobby s = new Lobby();
s.runServer();
}
public void runServer() throws IOException, ClassNotFoundException {
registerServer();
new Thread( () -> {
try {
ServerSocket serverSocket = new ServerSocket(PORT);
System.out.println("Server waiting for connections...");
while (true) {
Socket socket = serverSocket.accept();
System.out.println("User 1 is now connected");
clientNumber++;
new ObjectOutputStream(socket.getOutputStream()).writeObject("You are connected man");
Socket socket2 = serverSocket.accept();
System.out.println("User 2 is now connected");
clientNumber++;
// ObjectOutputStream objectOutputStream2 = new ObjectOutputStream(socket2.getOutputStream());
// objectOutputStream2.writeObject("You are player number " + clientNumber + ". Waiting for other players to join");
new ServerThread(socket, socket2).start();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}).start();
}
private void registerServer() throws UnknownHostException, IOException, ClassNotFoundException {
// Method for establishing a connection to the MainServer
Socket socket = new Socket(MainServer.HOST, MainServer.PORT);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
objectOutputStream.writeObject(this);
System.out.println((String) objectInputStream.readObject());
}
public class ServerThread extends Thread {
public Socket socket = null;
public Socket socket2 = null;
ServerThread(Socket socket, Socket socket2) {
this.socket = socket;
this.socket2 = socket2;
}
public void run() {
try {
// This method is for when the client want's to connect to the lobby
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
System.out.println("User 1 is now connected");
ObjectInputStream objectInputStream2 = new ObjectInputStream(socket2.getInputStream());
ObjectOutputStream objectOutputStream2 = new ObjectOutputStream(socket2.getOutputStream());
System.out.println("User 2 is now connected");
BoardGameClient joined = (BoardGameClient) objectInputStream.readObject();
System.out.println(joined.name + " is now connected.");
while(true) {
objectOutputStream.writeObject("You joined the server.");
objectOutputStream.writeObject("You are player Number " + 1);
objectOutputStream.writeObject("Press '1' if you are ready");
objectOutputStream2.writeObject("You joined the server.");
objectOutputStream2.writeObject("You are player Number " + 2);
objectOutputStream2.writeObject("Press '1' if you are ready");
if(objectInputStream.readObject().equals(1)) {
playerNumberReady++;
}
if(objectInputStream2.readObject().equals(1)) {
playerNumberReady++;
}
if(playerNumberReady != 2) {
allPlayersReady = false;
} else {
allPlayersReady = true;
}
if (allPlayersReady == false) {
objectOutputStream.writeObject("Waiting...");
objectOutputStream2.writeObject("Waiting...");
}
if (allPlayersReady == true) {
objectOutputStream.writeObject("Lets GO");
objectOutputStream2.writeObject("Lets GO");
}
while (true) {
System.out.println(objectInputStream.readObject());
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
And the client
package main;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
import java.util.concurrent.Semaphore;
import master.MainServer;
public class BoardGameClient implements Serializable {
private int playerName;
private static final long serialVersionUID = -6224L;
public String name = "User";
private transient Socket socket;
public transient Scanner input = new Scanner(System.in);
public static void main(String[] args) {
BoardGameClient c = new BoardGameClient();
if (args.length > 0) {
c.name = args[0];
}
try {
c.joinServer();
} catch (ClassNotFoundException | IOException e) {
System.out.println("Failed to join server.");
e.printStackTrace();
}
}
public void joinServer() throws UnknownHostException, IOException, ClassNotFoundException {
socket = new Socket(Lobby.HOST, Lobby.PORT);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
while(true) {
objectOutputStream.writeObject(this);
BufferedReader inputReader = new BufferedReader(new InputStreamReader(System.in));
System.out.println(objectInputStream.readObject());
System.out.println(objectInputStream.readObject());
System.out.println(objectInputStream.readObject());
int ready = input.nextInt();
objectOutputStream.writeObject(ready);
System.out.println(objectInputStream.readObject());
objectOutputStream.writeObject(name + ": " + inputReader.readLine());
}
}
}
I sincerely hope, that someone will be able to help me out <3
Firstly, there's a few things that bug me about this code. Not to sound condescending but you need to avoid rewriting code as much as possible. What happens if you want 3 or more players in the future? Currently you'd have to manually create a whole socket eg socket3, and then rewrite all the code you've already written. This is bad. You've manually spent the time creating 2 sockets and then created 2 streams for both of these sockets etc etc.
This can be automated don't you think?
Secondly, you have a lot of public variables. Unless they are static and final, for the most part you should keep variables as private.
I've tinkered with your lobby class as seen below, which is more scalable. It's not perfect by any means, but I feel illustrates the direction of improvement you should be heading for. Look up SOLID OOP principles, they'll help you guaranteed.
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* The Class Server.
*/
public class Lobby implements Serializable {
private static final long serialVersionUID = -21654L;
public static final int PORT = 4445;
public static final int MAX_USERS = 5000;
public static final String HOST = "localhost";
private static final int MIN_USERS = 2;
private String name = "Lobby Server";
private int clientNumber;
private boolean gameRunning = false;
// set of client connections
private final Set<ServerThread> clientConnectionThreads = new LinkedHashSet<>();
public static void main(String[] args) throws IOException, ClassNotFoundException {
Lobby s = new Lobby();
s.createLobby();
}
public void createLobby() throws IOException, ClassNotFoundException {
// waits for all players to ready up in a different thread
new Thread(this::waitReady).start();
registerServer();
// Listens for clients
runServer();
}
public void runServer() {
// closes serverSocket automatically in this way
try (ServerSocket serverSocket = new ServerSocket(PORT)) {
System.out.println("Server waiting for connections...");
long ids = 0;
while (!gameRunning) {
// accepts a new client connection
Socket socket = serverSocket.accept();
if (clientConnectionThreads.size() >= MAX_USERS) {
// tell user server is full and dont add the connection
} else {
// calculates the new id of the incoming player and adds them to the lobby
ids++;
this.clientConnectionThreads.add(new ServerThread(ids, socket));
System.out.println("User " + ids + " is now connected");
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
/*
* loops until every player is ready and there is enough players and then starts
* the game.
*/
public void waitReady() {
while (true) {
try {
if (areAllReady() && this.clientConnectionThreads.size() >= MIN_USERS) {
startGame();
return;
}
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// returns true if all users are ready
public boolean areAllReady() {
return clientConnectionThreads.stream().allMatch(ServerThread::isReady);
}
public void startGame() {
System.out.println("Starting game...");
this.gameRunning = true;
clientConnectionThreads.forEach(ServerThread::startGame);
// do game stuff
}
// i havent touched this function
private void registerServer() throws UnknownHostException, IOException, ClassNotFoundException {
// Method for establishing a connection to the MainServer
Socket socket = new Socket(MainServer.HOST, MainServer.PORT);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
objectOutputStream.writeObject(this);
System.out.println((String) objectInputStream.readObject());
}
public class ServerThread extends Thread {
private final Socket socket;
private final ObjectInputStream in;
private final ObjectOutputStream out;
private final long id;
boolean ready = false;
private ServerThread(long id, Socket socket) throws IOException {
// does some basic initialization
this.socket = socket;
this.id = id;
in = new ObjectInputStream(socket.getInputStream());
out = new ObjectOutputStream(socket.getOutputStream());
// starts this connection thread
this.start();
}
public boolean isReady() {
return ready;
}
public void run() {
try {
// sets up the client and waits for their input
BoardGameClient joined = (BoardGameClient) in.readObject();
System.out.println(joined.name + " is now connected.");
out.writeObject("You joined the server.");
out.writeObject("You are player Number " + id);
out.writeObject("Press '1' if you are ready");
out.flush();
// waits for user to return ready
while (!ready) {
try {
int input = in.readInt();
System.out.println("input: " + input);
ready = input == 1;
} catch (ClassCastException e) {
e.printStackTrace();
}
}
out.writeObject("Waiting for players...");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void startGame() {
// send client message etc etc
}
}
public String getName() {
return name;
}
}
I basically didn't change any of the other classes, except a few lines within the client class to make this work. (I've changed the ready input type from writeObject() to writeInt())
I haven't tested this for problems, but I know it works at least on a basic level.
I also suggest using writeUTS()/readUTS() instead of writeObject()/readObject() for sending and receiving Strings across streams as this will add extra complexity to the code.

NIO chat application not working properly for multiple clients

I've been working on a NIO-based chat application of quite trivial logic: any message sent by any client should be visible to the rest of the users.
Right now, I'm sort of in the middle of the work, I've got pretty complete classes of the clients (and their GUI part) and the server but I've stumbled on a problem I couldn't find any solution on anywhere. Namely, if I run an instance of the server and one instance of the client, in my consoles (one for client, one for the server) I see a nice, expected conversation. However, after adding additional client, this newly created client doesn't get responses from the server - the first still has a valid connection.
I'm not thinking about broadcasting messages to all the clients yet, now I'd like to solve the problem of the lack of proper communication between each of my clients and the server since, I think that broadcasting shouldn't be so big a deal if the communication is fine.
I'd like to also add that I've tried many other ways of instantiating the clients: in one thread, firstly instantiating the clients then applying methods on them, I've event tried using invokeLater from SwingUtilities, since that's the proper way to boot up GUI. Sadly, neither worked.
What should I change to achieve proper communication between clients and the server? What am I doing wrong?
This is the log from client console:
Awaiting message from: client2...
Awaiting message from: client1...
after creating the clients - before any action
1 Message: client1 :: simpleMess1
2 started pushing message from: client1
3 Server response on client side: ECHO RESPONSE: client1 :: simpleMess1
4 Message: client2 :: simpleMessage from c2
5 started pushing message from: client2
6
7 -- No response from client2. AND next try from client2 shows no log at all (!)
8
9 Message: client1 :: simple mess2 from c1
10 started pushing message from: client1
11 Server response on client side: ECHO RESPONSE: client1 :: simpleMess1
And the log from server side console:
1 Server started...
2 S: Key is acceptable
3 S: Key is acceptable
4
5 -- after creating the clients before any action
6 S: Key is readable.
The console output clearly shows that the server receives acceptable keys from both clients but it suggest also that only one SocketChannel has a SelectionKey of readable type, but I've got no clue why. Moreover, I think that the order of creating the clients doesn't matter because as I tested: the client that talks properly with the server is always the one that starts communication as first.
Below I'm posting my Server and Client classes code, hoping You'll Guys help me sort it out.
Firstly, Server class:
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Set;
public class Server {
private ServerSocketChannel serverSocketChannel = null;
private Selector selector = null;
private StringBuffer messageResponse = new StringBuffer();
private static Charset charset = Charset.forName("ISO-8859-2");
private static final int BSIZE = 1024;
private ByteBuffer byteBuffer = ByteBuffer.allocate(BSIZE);
private StringBuffer incomingClientMessage = new StringBuffer();
Set<SocketChannel> clientsSet = new HashSet<>();
public Server(String host, int port) {
try {
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.socket().bind(new InetSocketAddress(host, port));
selector = Selector.open();
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
}
catch (Exception exc) {
exc.printStackTrace();
System.exit(1);
}
System.out.println("Server started...");
serviceConnections();
}
private void serviceConnections() {
boolean serverIsRunning = true;
while (serverIsRunning) {
try {
selector.select();
Set keys = selector.selectedKeys();
Iterator iter = keys.iterator();
while (iter.hasNext()) {
SelectionKey key = (SelectionKey) iter.next();
iter.remove();
if (key.isAcceptable()) {
System.out.println("\tS: Key is acceptable");
SocketChannel incomingSocketChannel = serverSocketChannel.accept();
incomingSocketChannel.configureBlocking(false);
incomingSocketChannel.register(selector, SelectionKey.OP_READ);
clientsSet.add(incomingSocketChannel);
continue;
}
if (key.isReadable()) {
System.out.println("\tS: Key is readable.");
SocketChannel incomingSocketChannel = (SocketChannel) key.channel();
serviceRequest(incomingSocketChannel);
continue;
}
}
}
catch (Exception exc) {
exc.printStackTrace();
continue;
}
}
}
private void serviceRequest(SocketChannel sc) {
if (!sc.isOpen()) return;
incomingClientMessage.setLength(0);
byteBuffer.clear();
try {
while (true) {
int n = sc.read(byteBuffer);
if (n > 0) {
byteBuffer.flip();
CharBuffer cbuf = charset.decode(byteBuffer);
while (cbuf.hasRemaining()) {
char c = cbuf.get();
if (c == '\r' || c == '\n') break;
incomingClientMessage.append(c);
}
}
writeResp(sc, "ECHO RESPONSE: " + incomingClientMessage.toString());
}
}
catch (Exception exc) {
exc.printStackTrace();
try {
sc.close();
sc.socket().close();
}
catch (Exception e) {
}
}
}
private void writeResp(SocketChannel sc, String addMsg)
throws IOException {
messageResponse.setLength(0);
messageResponse.append(addMsg);
messageResponse.append('\n');
ByteBuffer buf = charset.encode(CharBuffer.wrap(messageResponse));
sc.write(buf);
}
//second version - with an attempt to acomlish broadcasting
private void writeResp(SocketChannel sc, String addMsg)
throws IOException {
messageResponse.setLength(0);
messageResponse.append(addMsg);
messageResponse.append('\n');
ByteBuffer buf = charset.encode(CharBuffer.wrap(messageResponse));
System.out.println("clientsSet: " + clientsSet.size());
for (SocketChannel socketChannel : clientsSet) {
System.out.println("writing to: " + socketChannel.getRemoteAddress());
socketChannel.write(buf);
buf.rewind();
}
}
public static void main(String[] args) {
try {
final String HOST = "localhost";
final int PORT = 5000;
new Server(HOST, PORT);
}
catch (Exception exc) {
exc.printStackTrace();
System.exit(1);
}
}
}
and the Client class:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
private ClientView clientView;
private String hostName;
private int port;
private String clientName;
private Socket socket = null;
private PrintWriter printWriterOUT = null;
private BufferedReader bufferedReaderIN = null;
public Client(String hostName, int port, String clientName) {
this.hostName = hostName;
this.port = port;
this.clientName = clientName;
initView();
}
public void handleConnection() {
try {
socket = new Socket(hostName, port);
printWriterOUT = new PrintWriter(socket.getOutputStream(), true);
bufferedReaderIN = new BufferedReader(new InputStreamReader(socket.getInputStream()));
waitForIncomingMessageFromClientView();
bufferedReaderIN.close();
printWriterOUT.close();
socket.close();
}
catch (UnknownHostException e) {
System.err.println("Unknown host: " + hostName);
System.exit(2);
}
catch (IOException e) {
System.err.println("I/O err dla");
System.exit(3);
}
catch (Exception exc) {
exc.printStackTrace();
System.exit(4);
}
}
public void initView() {
clientView = new ClientView(clientName);
}
public void waitForIncomingMessageFromClientView() {
System.out.println("Awaiting message from: " + clientName + "...");
while (true) {
if (clientView.isSent) {
System.out.println("Message: " + clientView.getOutgoingMessage());
pushClientViewMessageToServer();
clientView.setIsSent(false);
}
}
}
public void pushClientViewMessageToServer() {
String clientViewMessage = clientView.getOutgoingMessage();
System.out.println("started pushing message from: " + clientView.getClientName());
try {
printWriterOUT.println(clientViewMessage);
String resp = bufferedReaderIN.readLine();
System.out.println("Server response on client side: " + resp);
}
catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Thread thread1 = new Thread(new Runnable() {
#Override
public void run() {
Client c1 = new Client("localhost", 5000, "client1");
c1.handleConnection();
}
});
thread1.start();
Thread thread2 = new Thread(new Runnable() {
#Override
public void run() {
Client c2 = new Client("localhost", 5000, "client2");
c2.handleConnection();
}
});
thread2.start();
}
}
I'll apprecaite any help from You Guys.
EDIT:
the second version of writeResp method attempting to broadcast echo to all the clients produces such log:
Server started...
clientsSet: 2
writing to: /127.0.0.1:63666
writing to: /127.0.0.1:63665
clientsSet: 2
writing to: /127.0.0.1:63666
writing to: /127.0.0.1:63665
It seems like there are two clients and I'm wondering why they don't get proper reply from the server.
while (true) {
int n = sc.read(byteBuffer);
if (n > 0) {
byteBuffer.flip();
CharBuffer cbuf = charset.decode(byteBuffer);
while (cbuf.hasRemaining()) {
char c = cbuf.get();
if (c == '\r' || c == '\n') break;
incomingClientMessage.append(c);
}
}
There is a major problem here. If read() returns -1 you should close the SocketChannel, and if it returns -1 or zero you should break out of the loop.

How do I set up my Java chatroom program to work with port forwarding?

I watched a tutorial on simple Java networking, and the tutorial showed the server and client application running on the same computer and it worked, I was wondering if there's a way to make it work on different computers in different homes using port forwarding or something else; Here is my code:
Server.java:
package com.cloud.server;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
/**
* The Server class extends JFrame and contains all of the code pertaining to the GUI and the server
*
* #author mcjcloud
*
*/
public class Server extends JFrame
{
private JTextField userInput;
private JTextArea convo;
private ObjectOutputStream output;
private ObjectInputStream input;
private ServerSocket server; // establishes server
private Socket connection; // establishes connection with other computer
/**
* Constructor (basically just sets up the GUI and actionListener(s)
*/
public Server()
{
super("Cloud Messenger");
userInput = new JTextField();
userInput.setEditable(false);
userInput.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
sendMessage(e.getActionCommand());
userInput.setText("");
}
});
add(userInput, BorderLayout.SOUTH);
// set up convo (JTextArea)
convo = new JTextArea();
add(new JScrollPane(convo));
setSize(500, 700);
setLocationRelativeTo(null);
setVisible(true);
}
/**
* startServer() method waits for connection, sets up connection and manages chat
*/
public void startServer()
{
try
{
server = new ServerSocket(6789, 100, InetAddress.getByName("0.0.0.0")); // (port number, backlog) backlog (aka qlength) = "how many people can connect at a time"
while(true) // infinite loop
{
try
{
waitForConnection(); // first set up the connection
setupStreams(); // set up the streams
chat(); // enable the chat and things
}
catch(EOFException eofe) // EOF = EndOfStream (meaning the input/output stream ended)
{
showMessage("Connection terminated.");
}
finally
{
cleanUpConnection();
}
}
}
catch(IOException io)
{
io.printStackTrace();
}
}
/**
* waitForConnection() method will wait for the connection, then display connection info
*
* #throws IOException
*/
private void waitForConnection() throws IOException
{
showMessage("Waiting for connection...");
connection = server.accept(); // listens for a connection
showMessage("Now connected to " + connection.getInetAddress().getHostName());
}
/**
* setupStream() method gets a stream to send/recieve data
*/
private void setupStreams() throws IOException
{
// setup output stream
output = new ObjectOutputStream(connection.getOutputStream()); // create pathway to allow us to connect to the computer the socket is connected to
output.flush();
// setup input stream
input = new ObjectInputStream(connection.getInputStream()); // create pathway to receive messages
showMessage("Stream setup success.");
}
/**
* chat() method code runs during conversation
*/
private void chat() throws IOException
{
String message = "Chatting enabled";
showMessage(message);
setCanType(true);
do
{
try
{
message = (String) input.readObject();
showMessage(message);
}
catch(ClassNotFoundException cnfe)
{
showMessage("Message recieve failed (Other person's problem)");
}
}
while(!message.equals("CLIENT - /terminate"));
}
/**
* cleanUpConnection() method cleans up the stream and things after the chat has ended
*/
private void cleanUpConnection()
{
showMessage("Closing connection...");
setCanType(false);
try
{
output.close();
input.close();
connection.close();
}
catch(IOException io)
{
io.printStackTrace();
}
}
/**
* sendMessage(String) method sends whatever message you type
*
* #param message is what is going to be shown
*/
private void sendMessage(String message)
{
try
{
output.writeObject("SERVER - " + message); // write the message to the outputstream
output.flush();
showMessage("SERVER - " + message);
}
catch(IOException io)
{
convo.append("ERROR: Message can't be sent.");
}
}
/**
* showMessage(String)shows whatever needs to be shown on the JTextArea
*/
private void showMessage(String message)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
convo.append(" " + message + "\n");
}
});
}
/**
* setCanType() method decides whether or not a user can type
*
* #param canType
*/
private void setCanType(boolean canType)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
userInput.setEditable(canType);
}
});
}
}
InvokeServer.java:
package com.cloud.server;
import javax.swing.JFrame;
public class InvokeServer
{
public static void main(String[] args)
{
Server server = new Server();
server.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
server.startServer();
}
}
Client.java:
package com.cloud.client;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.Socket;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
/**
* Client class is the sister of the Server class in the server application, contains all the code to build GUI and send info to server and receive
*
* #author mcjcloud
*
*/
public class Client extends JFrame
{
private JTextField userInput;
private JTextArea convo;
private ObjectOutputStream output;
private ObjectInputStream input;
private String message = "";
private String serverIP; // connecting to a specific server
private Socket connection;
public Client(String host)
{
super("Cloud Messenger");
serverIP = host;
userInput = new JTextField();
userInput.setEditable(false);
userInput.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
sendMessage(e.getActionCommand());
userInput.setText("");
}
});
add(userInput, BorderLayout.SOUTH);
convo = new JTextArea();
add(new JScrollPane(convo));
setSize(500, 700);
setLocationRelativeTo(null);
setVisible(true);
}
/**
* startClient() method invokes the whole conversation
*/
public void startClient()
{
try
{
boolean connected = false;
showMessage("Connecting to server...");
while(!connected)
{
try
{
connected = connectToServer();
}
catch(ConnectException ce)
{
// do nothing
}
}
setupStreams();
chat();
}
catch(EOFException eofe)
{
sendMessage("Connection terminated.");
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
finally
{
cleanUpConnection();
}
}
/**
* connectToServer() establishes connection with the server application
*
* #throws IOException
*/
private boolean connectToServer() throws IOException
{
connection = new Socket(InetAddress.getByName(serverIP), 6789);
showMessage("Now connected to " + connection.getInetAddress().getHostName());
return true;
}
/**
* setupStream() method gets a stream to send/recieve data
*/
private void setupStreams() throws IOException
{
// setup output stream
output = new ObjectOutputStream(connection.getOutputStream()); // create pathway to allow us to connect to the computer the socket is connected to
output.flush();
// setup input stream
input = new ObjectInputStream(connection.getInputStream()); // create pathway to receive messages
showMessage("Stream setup success.");
}
/**
* chat() method code runs during conversation
*/
private void chat() throws IOException
{
String message = "Chatting enabled";
showMessage(message);
setCanType(true);
do
{
try
{
message = (String) input.readObject();
showMessage(message);
}
catch(ClassNotFoundException cnfe)
{
showMessage("Message recieve failed (Other person's problem)");
}
}
while(!message.equals("SERVER - /terminate"));
}
/**
* cleanUpConnection() method cleans up the stream and things after the chat has ended
*/
private void cleanUpConnection()
{
showMessage("Closing connection...");
setCanType(false);
try
{
output.close();
input.close();
connection.close();
}
catch(IOException io)
{
io.printStackTrace();
}
}
/**
* sendMessage(String) method sends whatever message you type
*
* #param message is what is going to be shown
*/
private void sendMessage(String message)
{
try
{
output.writeObject("CLIENT - " + message); // write the message to the outputstream
output.flush();
showMessage("CLIENT - " + message);
}
catch(IOException io)
{
convo.append("ERROR: Message can't be sent.");
}
}
/**
* showMessage(String) shows whatever needs to be shown on the JTextArea
*/
private void showMessage(String message)
{
SwingUtilities.invokeLater(new Runnable() // USE THIS RUNNABLE TO UPDATE GUI
{
public void run()
{
convo.append(" " + message + "\n");
}
});
}
/**
* setCanType() method decides whether or not a user can type
*
* #param canType
*/
private void setCanType(boolean canType)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
userInput.setEditable(canType);
}
});
}
}
InvokeClient.java:
package com.cloud.client;
import javax.swing.JFrame;
public class InvokeClient
{
public static void main(String[] args)
{
Client client = new Client("99.25.233.116");
client.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
client.startClient();
}
}
Note:
I tried setting up port forwarding on my home network with the port 6789 to one of my laptops, and that's the laptop I run the server application on.
I solved it. I just undid and redid the port forwarding again and it worked with the public IP address. Thank you all for your help

Java NIO - SocketChannel.write() on server many times but Client only receive result once

I'm doing an exercise requires making a server - client chat program using Java Non-Blocking IO. At the moment, the way the program works is simple: when a client send a message to the server, the server (which already keep track of all the clients) echo the message back to all the clients.
This is my some parts of my server-side code:
public static ByteBuffer str_to_bb(String msg) {
try {
return encoder.encode(CharBuffer.wrap(msg));
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
private static void broadcastMessage(String nickname, String message) {
System.out.println(">clientSocketChannels size " + clientSocketChannels.size());
Iterator clientSocketChannelsIterator = clientSocketChannels.iterator();
while (clientSocketChannelsIterator.hasNext()) {
SocketChannel sc = (SocketChannel) clientSocketChannelsIterator.next();
try {
ByteBuffer bb = str_to_bb(message);
System.out.println("bufferRemaining: " + bb.remaining()); // returns 2048
int writeResult = sc.write(bb);
System.out.println("writeResult: " + writeResult); // returns 2048
} catch (IOException e) {
e.printStackTrace();
}
}
}
The following is my client-side code:
import javax.swing.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
/**
* Created by ThaiSon on 7/6/2015.
*/
public class ChatRoomClientGUI {
private JTextArea textAreaMessages;
private JTextField textFieldMessage;
private JButton buttonSendMsg;
private JPanel jPanel1;
private JLabel txtFieldInfo;
private static InetAddress inetAddress;
private static final int PORT = 1234;
private static Socket socket = null;
private static Scanner input = null;
private static PrintWriter output = null;
private static ChatRoomClientGUI singleton;
public ChatRoomClientGUI() {
singleton = this;
buttonSendMsg.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
if (e.getButton() == MouseEvent.BUTTON1) {
String message = textFieldMessage.getText();
output.println(message);
textFieldMessage.setText("");
}
}
});
}
public static void main(String[] args) {
JFrame promptFrame = new JFrame();
Object nickname = JOptionPane.showInputDialog(promptFrame, "Enter your nickname:");
promptFrame.dispose();
JFrame frame = new JFrame("ChatRoomClientGUI");
frame.setContentPane(new ChatRoomClientGUI().jPanel1);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
System.out.println("> Client with nickname " + nickname);
try {
inetAddress = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
accessServer(nickname.toString());
}
private static void accessServer(String nickname) {
try {
socket = new Socket(inetAddress, PORT);
input = new Scanner(socket.getInputStream());
output = new PrintWriter(socket.getOutputStream(), true);
output.println(nickname); // Register nickname with the server
//TODO update the txtFieldInfo content
// Create a new thread to listen to InputStream event
InputStreamEvent inputStreamEvent = new InputStreamEvent(socket);
inputStreamEvent.start();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void handleInputStream(){
String response = input.nextLine();
System.out.println("TODO " + response);
singleton.textAreaMessages.append(response + "\n");
}
static class InputStreamEvent extends Thread{
Socket socket;
public InputStreamEvent(Socket socket){
this.socket = socket;
}
public void run(){
try {
InputStream inputStream = socket.getInputStream();
byte[] buffer = new byte[2048];
int read;
while (true){
if(inputStream.available() > 0){
handleInputStream();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
The problem I'm facing with now is that when I use a client (which works well with the old multithreaded server) to send message to the server, the client only get return the first message it sends. All the next responses from the server is empty (the server does send back, but only an empty message).
So my attempts to debug includes:
check if the messages from the client has reach the server or not. They does.
log the buffer.remaining() and socketChannel.write(buffer) result as shown above, all the log result seems to be normal to me.
Hope you guys can help me with this.
This:
if(inputStream.available() > 0){
Get rid of this test. With it, your client is smoking the CPU. Without it, it will block in readLine() as God intended.
Are you sure your server is still sending lines? with line terminators? If it isn't, readLine() will block forever looking for one, until end of stream or an exception occurs.
I referred the code explain by EJP on this link Java NIO Server/Client Chat App - sending data only by closing the socket
it solves my problem. use this code
import java.nio.channels.SocketChannel;
import java.nio.channels.Selector;
import java.nio.ByteBuffer;
import java.io.IOException;
import java.util.Scanner;
import java.nio.channels.SelectionKey;
import java.net.InetSocketAddress;
public class Client {
public static void main(String args[]) {
try {
ByteBuffer buf = ByteBuffer.allocate(200);
Scanner scanner = new Scanner(System.in);
Selector selector = Selector.open();
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_CONNECT|SelectionKey.OP_READ|SelectionKey.OP_WRITE);
boolean isConnected = socketChannel.connect(new InetSocketAddress("localhost", 5000));
if(isConnected) {
System.out.println("Connected, de-registering OP_CONNECT");
}
new Thread(new Runnable(){
private SocketChannel socketChannel;
private Selector selector;
public Runnable init(SocketChannel socketChannel, Selector selector) {
this.socketChannel = socketChannel;
this.selector = selector;
return this;
}
public void run() {
try {
ByteBuffer buf = ByteBuffer.allocate(200);
while(!Thread.interrupted()) {
int keys = selector.select();
if(keys > 0) {
for(SelectionKey key : selector.selectedKeys()) {
if(key.isConnectable()) {
boolean finishConnectResult = socketChannel.finishConnect();
socketChannel.register(this.selector, SelectionKey.OP_WRITE|SelectionKey.OP_READ);
System.out.println("Finished Connect : " + finishConnectResult);
}
if(key.isReadable()) {
int bytesRead = 0;
while((bytesRead = socketChannel.read(buf)) > 0) {
buf.flip();
while(buf.hasRemaining()) {
System.out.print((char)buf.get());
}
buf.clear();
}
if(bytesRead == -1) {
key.channel().close();
}
}
}
}
Thread.sleep(10);
}
} catch(IOException e) {
e.printStackTrace();
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}.init(socketChannel, selector)).start();
while(true) {
while(scanner.hasNextLine()) {
buf.clear();
buf.put(scanner.nextLine().getBytes());
buf.flip();
socketChannel.write(buf);
buf.flip();
}
}
} catch(IOException e) {
e.printStackTrace();
}
}
}
I have done the mistake setting this flag
key.interestOps(SelectionKey.OP_READ);
)
instead of below.
use this
socketChannel.register(this.selector, SelectionKey.OP_WRITE|SelectionKey.OP_READ);

Stuck with Multi-Client Chat Application

I'm trying to make a MultiClient Chat Application in which the chat is implemented in the client window. I've tried server and client code for the same. I've got two problems:
A. I believe the code should work but, server to client connections are just fine but information isn't transferred between clients.
B. I need a way to implement private one-to-one chat in case of more than two clients, I've used a class to store the information of the Socket object returned for each connection being established, but I can't figure out how to implement it.
The server code is:
import java.io.*;
import java.net.*;
class ClientInfo {
Socket socket;
String name;
public ClientInfo(Socket socket, String name) {
this.socket = socket;
this.name = name;
}
}
public class server {
private ObjectInputStream input[] = null;
private ObjectOutputStream output[] = null;
private String value = null;
private static ServerSocket server;
private Socket connection = null;
private static int i = -1;
public static void main(String args[]) {
try {
server = new ServerSocket(1500, 100);
while (true) {
System.out.println("Waiting for connection from client");
Socket connection = server.accept();
i++;
System.out.println("Connection received from " + (i + 1) + " source(s)");
//System.out.println(i);
new ClientInfo(connection, "Client no:" + (i + 1));
innerChat inc = new server().new innerChat(connection);
}
} catch (Exception e) {
System.out.println("Error in public static void main! >>>" + e);
}
}// end of main!!!
class innerChat implements Runnable {
private Socket connection = null;
public innerChat(Socket connection) {
this.connection = connection;
Thread t;
t = new Thread(this);
t.start();
}
public void run() {
try {
output[i] = new ObjectOutputStream(connection.getOutputStream());
output[i].flush();
input[i] = new ObjectInputStream(connection.getInputStream());
} catch (Exception e) {
}
}
}
}
And the client code is
import java.net.*;
import java.io.*;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.*;
import java.awt.event.*;
public class ChatappClient {
private static int port = 1500;
JFrame window = new JFrame("Chat");
JButton sendBox = new JButton("Send");
JTextField inputMsg = new JTextField(35);
JTextArea outputMsg = new JTextArea(10, 35);
private ObjectInputStream input;
private ObjectOutputStream output;
public static void main(String[] args) throws Exception {
ChatappClient c = new ChatappClient();
c.window.setVisible(true);
c.window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
c.run();
}
public ChatappClient() {
inputMsg.setSize(40, 20);
sendBox.setSize(5, 10);
outputMsg.setSize(35, 50);
inputMsg.setEditable(true);
outputMsg.setEditable(false);
window.getContentPane().add(inputMsg, "South");
window.getContentPane().add(outputMsg, "East");
window.getContentPane().add(sendBox, "West");
window.pack();
sendBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
output.writeObject(inputMsg.getText());
outputMsg.append("\n" + "Client>>>" + inputMsg.getText());
output.flush();
} catch (IOException ie) {
outputMsg.append("Error encountered! " + ie);
}
inputMsg.setText("");
}
});
inputMsg.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
output.writeObject(inputMsg.getText());
outputMsg.append("\n" + "Client>>>" + inputMsg.getText());
output.flush();
} catch (IOException ie) {
outputMsg.append("Error encountered! " + ie);
}
inputMsg.setText("");
}
});
}
private void run() throws IOException {
Socket clientSocket = new Socket("127.0.0.1", port);
output = new ObjectOutputStream(clientSocket.getOutputStream());
output.flush();
input = new ObjectInputStream(clientSocket.getInputStream());
outputMsg.append("I/O Success");
String value = null;
while (true) {
try {
value = (String) input.readObject();
} catch (Exception e) {
}
outputMsg.append(value + "\n");
}
}
}
Your code looks like it could be improved quite a bit. Your main method for instance should have none of that code in it. It should start your Server class, and that's it (and note that class names should begin with an upper case letter as per Java standards which I strongly advise you to follow).
I'm trying to make a MultiClient Chat Application in which a Server does nothing but listen and create connections.
The Server is going to have to do more than that. It will need to create Clients, it will need to maintain a collection such as an ArrayList of Clients such as an ArrayList<ChatappClient> Otherwise how do you expect the Server to connect two Clients together?
I think that in all you're going to need to think the structure and connections of this program out in more depth before starting to write code.

Categories

Resources