I have these following code for communication between client and server. I can run client and server within same machine. But if I am trying to run client from a different machine I cant run. Also I need another client so that this 2 clients can chat with each other through server.
Now server and client can exchange data among each other. But I want another client so that only this 2 clients can exchanging data among themselves through the server.
Client.java
public class Clin extends JFrame{
private JLabel statuslabel,chatlabel,instruction,instruction1;
private JTextArea statusarea;
private JPanel chatbox;
private JScrollPane statusscroll;
private JButton Embed,Send,Decode;
private Socket connection;
private ObjectInputStream input;
private ObjectOutputStream output;
private JCheckBox []checks;
private BufferedImage[] images;
private ButtonGroup grp;
private String ServerIP;
public BufferedImage Bufim;
public Clin cli;
public JLabel setlabel;
private int JC;
private String security=null;
public Clin(String host){
super("Client");
Bufim=null;
cli=this;
JC=-1;
ServerIP=host;
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setBounds(720,20,700,700);
this.setResizable(false);
this.setLayout(null);
this.getContentPane().setBackground(Color.RED);
public static void main(String[] args) throws InterruptedException,
InvocationTargetException {
Clin cli=new Clin("localhost");
cli.startRunning();
}
public void startRunning(){//////////////////////////////
try{
connectToServer();
setupStreams();
whileChatting();
}catch(EOFException eofException){
showMessage("\nClient terminated the connection");
}catch(IOException ioException){
ioException.printStackTrace();
}finally{
closeConnection();
}
}
private void connectToServer() throws IOException{
showMessage("\nAttempting connection...");
connection = new Socket(InetAddress.getByName(ServerIP), 7777);
showMessage("\nConnection Established! Connected to: " +
connection.getInetAddress().getHostName());
}
private void setupStreams() throws
IOException{//////////////////////////////////////////////////
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
showMessage("\nStreams are now setup");
}
private void whileChatting() throws
IOException{///////////////////////////////////
ableToSend(true);
Object mess=null;
try {
showMessage("\n" + (String)input.readObject());
security=JOptionPane.showInputDialog(this,"Hey Client please
provide the OTP you just recieved!");
if(security==null){
security="-";
}
sendMessage(security);
String rs=(String)input.readObject();
showMessage("\n" + ((rs.equals("CLOSE"))?"":rs));
} catch (ClassNotFoundException ex) {
Logger.getLogger(Clin.class.getName()).log(Level.SEVERE,
null, ex);
}
do{
try{
mess =input.readObject();
if(mess instanceof String){
if(!((String)mess).equals("CLOSE"))
showMessage("\n" + mess);
}
else {
ByteArrayInputStream bin=new
ByteArrayInputStream((byte[]) mess);
BufferedImage ms=ImageIO.read(bin);
displayMessage(ms);
bin.close();
}
}catch(Exception Ex){
showMessage("\nThe server has sent an unknown object!");
}
}while(mess instanceof byte[]||(mess!=null&&!
((String)mess).equals("CLOSE")));
}
server.java
public class Serv extends JFrame{
private JLabel statuslabel,chatlabel,instruction,instruction1;
private JTextArea statusarea;
private JPanel chatbox;
private JScrollPane statusscroll,scroll;
private JButton Embed,Send,Decode;
private ServerSocket server;
private Socket connection;
private ObjectInputStream input;
private ObjectOutputStream output;
private JCheckBox []checks;
private BufferedImage[] images;
private ButtonGroup grp;
public BufferedImage Bufim;
public Serv sser;
public JLabel setlabel;
private int JC;
private String security=null;
public Serv(){
super("Server");
Bufim=null;
sser=this;
JC=-1;
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setBounds(10,20,700,700);
this.setResizable(false);
this.setLayout(null);
this.getContentPane().setBackground(Color.RED);
public static void main(String[] args) throws InterruptedException,
InvocationTargetException {
Serv ser=new Serv();
ser.startRunning();
}
public void startRunning(){//////////////////////////////
try{
server = new ServerSocket(7777,100);
while(true){
try{
waitForConnection();
setupStreams();
whileChatting();
}catch(Exception eofException){
showMessage("\nServer ended the connection!");
} finally{
closeConnection();
}
}
} catch (IOException ioException){
ioException.printStackTrace();
}
}
private void waitForConnection() throws
IOException{/////////////////////////////////////
showMessage("\nWaiting for someone to connect...");
connection = server.accept();
showMessage("\nNow connected to " +
connection.getInetAddress().getHostName());
}
private void setupStreams() throws
IOException{//////////////////////////////////////////////////
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
showMessage("\nStreams are now setup");
}
private void whileChatting() throws
IOException{///////////////////////////////////
chatbox.removeAll();
this.repaint();
this.validate();
String s=JOptionPane.showInputDialog(this,"Hey Server please
set the OTP for Client!");
if(s.equals("")){
s="12345";
}
double dd;
while((dd=Math.random())<0.1){}
Integer xx=(int)(dd*100000);
//String s=xx.toString();
security=s;
String message = " You are now connected!\n Your OTP : "+s;
sendMessage(message);
try {
String ss=(String)input.readObject();
if(!ss.equals(security)){
sendMessage("Incorrect OTP !");
return;
}
else sendMessage("Verification Successfull !");
} catch (ClassNotFoundException ex) {
Logger.getLogger(Clin.class.getName()).log(Level.SEVERE,
null, ex);
}
ableToSend(true);
Object mess=null;
do{
try{
mess =input.readObject();
if(mess instanceof String){
if(!((String)mess).equals("CLOSE"))
showMessage("\n" + mess);
}
else {
ByteArrayInputStream bin=new ByteArrayInputStream((byte[]) mess);
BufferedImage ms=ImageIO.read(bin);
displayMessage(ms);
bin.close();
}
}catch(Exception Ex){
showMessage("\nThe user has sent an unknown object!");
}
}while(mess instanceof byte[]||(mess!=null&&!((String)mess).equals("CLOSE")));
}
Related
I have a server project and a client project (2 clients, a customer and an admin, from the customer GUI/Frame you can go to the admin GUI and move between GUIs as needed).
I have a button on each GUI/Frame which just sends a String to the server when it's clicked. I'm printing out the threads that are being created and I know that SwingWorkers Thread pool defaults to 10, and then it starts reusing threads.
I've noticed that once the created Threads hit 10, then the buttons to send requests to the server do not seem to send any data because the Thread pool is fully occupied.
I wanted to know how I can prevent this so a user can switch between the GUIs for x amount of time.
--
Server
public class Testserver {
private ServerSocket serverSocket;
private Socket client;
private final int PORT = 5432;
private ObjectOutputStream objectOutputStream;
private ObjectInputStream objectInputStream;
public Testserver() {
System.out.println(Thread.currentThread().getName());
try {
serverSocket = new ServerSocket(PORT);
System.out.println("Waiting for connection");
} catch (IOException ex) {
Logger.getLogger(Testserver.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void listenForClients() {
try {
while (true) {
client = serverSocket.accept();
System.out.println("client connected");
objectOutputStream = new ObjectOutputStream(client.getOutputStream());
objectInputStream = new ObjectInputStream(client.getInputStream());
processClient();
}
} catch (IOException ex) {
Logger.getLogger(Testserver.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new Testserver().listenForClients();
});
}
private void processClient() {
SwingWorker worker = new SwingWorker<>() {
#Override
protected Void doInBackground() throws Exception {
System.out.println(Thread.currentThread().getName());
do {
try {
String messageFromClient = (String) objectInputStream.readObject();
System.out.println("[CLIENT] " + messageFromClient);
} catch (IOException ex) {
Logger.getLogger(Testserver.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(Testserver.class.getName()).log(Level.SEVERE, null, ex);
}
} while (true);
}
};
worker.execute();
}
}
Customer Client
public class CustomerGUI extends JFrame implements ActionListener{
private Socket server;
private ObjectOutputStream objectOutputStream;
private ObjectInputStream objectInputStream;
private JButton btnAdminGUI,btnAddCustomer;
private final int PORT = 5432;
public CustomerGUI() {
btnAdminGUI = new JButton("Go to Admin GUI");
btnAddCustomer = new JButton("Add customer");
try {
server = new Socket("localhost", PORT);
System.out.println("Connected to server");
objectOutputStream = new ObjectOutputStream(server.getOutputStream());
objectInputStream = new ObjectInputStream(server.getInputStream());
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, "Error: " + ex.getMessage());
}
btnAdminGUI.addActionListener(this);
btnAddCustomer.addActionListener(this);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new CustomerGUI().setGUI();
});
}
public void setGUI() {
setLayout(new GridLayout(2,1));
add(btnAdminGUI);
add(btnAddCustomer);
setSize(300, 400);
setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == btnAdminGUI) {
new AdminGUI().setGUI();
dispose();
} else if(e.getSource() == btnAddCustomer) {
try {
objectOutputStream.writeObject("Added a customer");
objectOutputStream.flush();
} catch (IOException ex) {
Logger.getLogger(AdminGUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Admin Client(Pretty much the same as Customer)
public class AdminGUI extends JFrame implements ActionListener{
private Socket server;
private ObjectOutputStream objectOutputStream;
private ObjectInputStream objectInputStream;
private JButton btnCustomerGUI, btnAddAdmin;
private final int PORT = 5432;
public AdminGUI() {
btnCustomerGUI = new JButton("Go to Customer GUI");
btnAddAdmin = new JButton("Add admin");
try {
server = new Socket("localhost", PORT);
System.out.println("Connected to server");
objectOutputStream = new ObjectOutputStream(server.getOutputStream());
objectInputStream = new ObjectInputStream(server.getInputStream());
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, "Error: " + ex.getMessage());
}
btnAddAdmin.addActionListener(this);
btnCustomerGUI.addActionListener(this);
}
public void setGUI() {
setLayout(new GridLayout(2,1));
add(btnCustomerGUI);
add(btnAddAdmin);
setSize(300, 400);
setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == btnCustomerGUI) {
new CustomerGUI().setGUI();
dispose();
} else if(e.getSource() == btnAddAdmin) {
try {
objectOutputStream.writeObject("Added an admin");
objectOutputStream.flush();
} catch (IOException ex) {
Logger.getLogger(AdminGUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
EDIT
Updated working method code using FixedThreadPool
private void processClient() {
System.out.println("cores: " + Runtime.getRuntime().availableProcessors());
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
executor.execute(() -> {
System.out.println(Thread.currentThread().getName());
do {
try {
String messageFromClient = (String) objectInputStream.readObject();
System.out.println("[CLIENT] " + messageFromClient);
if (messageFromClient.equalsIgnoreCase("Exit")) {
System.out.println("closed connection to " + client);
closeConnections();
System.exit(0);
}
} catch (IOException ex) {
//JOptionPane.showMessageDialog(null, "Error: " + ex.getMessage());
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
//JOptionPane.showMessageDialog(null, "Error: " + ex.getMessage());
System.out.println("ClassNotFoundException in process client: " + ex.getMessage());
} catch (Exception ex) {
ex.printStackTrace();
//JOptionPane.showMessageDialog(null, "Error: " + ex.getMessage());
System.out.println("Exception in process client: " + ex.getMessage());
}
} while (true);
});
executor.shutdown();
}
I'm writing a chat room server which takes message from a chat client and broadcasts out the message to all users. This is an exercise from a book called An Introduction to Network Programming with Java: Java 7 Compatible with which I'm self-teaching Java networking basics. I wrote a GUI frontend for the chat room and implemented the server backend, following examples from the code in the book. However, when I tested the code with chat clients, the server seemed unable to receive clients' data. I can't figure out why. The code for the chat room (here it was made in command line mode for test purpose) and the client is as followings. Thank you.
// code for the server backend, problem seems to be lie in here.
/**
* The multiecho server itself
*/
package channelEchoServer;
import java.net.*;
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.util.*;
public class MultiEchoServerNIO {
private static ServerSocketChannel serverSocketChannel;
private static final int PORT = 1234;
private static Selector selector;
private static Vector<SocketChannel> socketChannelVec;
private static Vector<ChatUser> allUsers;
public static final int CAPACITY = 20;
public static final int BUFFER_SIZE = 2048;
public static final String NEW_LINE = System.lineSeparator();
public static void main(String[] args) {
ServerSocket serverSocket = null;
try {
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
serverSocket = serverSocketChannel.socket();
InetSocketAddress netAddress = new InetSocketAddress(PORT);
serverSocket.bind(netAddress);
selector = Selector.open();
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
}
catch (IOException ioEx) {
ioEx.printStackTrace();
System.exit(1);
}
socketChannelVec = new Vector<>(CAPACITY);
allUsers = new Vector<>(CAPACITY);
System.out.println("Server is opened ...");
processConnections();
}
private static void processConnections () {
do {
try {
int numKeys = selector.select();
System.out.println(numKeys + " keys selected.");
if (numKeys > 0) {
Set eventKeys = selector.selectedKeys();
Iterator keyCycler = eventKeys.iterator();
while (keyCycler.hasNext()) {
SelectionKey key = (SelectionKey)keyCycler.next();
int keyOps = key.readyOps();
if ((keyOps & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) {
acceptConnection(key);
continue;
}
if ((keyOps & SelectionKey.OP_READ) == SelectionKey.OP_READ) {
acceptData(key);
}
}
}
}
catch (IOException ioEx) {
ioEx.printStackTrace();
System.exit(1);
}
} while (true);
}
private static void acceptConnection (SelectionKey key) throws IOException {
SocketChannel socketChannel;
Socket socket;
socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
socket = socketChannel.socket();
System.out.println("Connection on " + socket + ".");
socketChannel.register(selector, SelectionKey.OP_READ);
socketChannelVec.add(socketChannel);
selector.selectedKeys().remove(key);
}
private static void acceptData (SelectionKey key) throws IOException {
SocketChannel socketChannel;
Socket socket;
ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
socketChannel = (SocketChannel) key.channel();
buffer.clear();
int numBytes = socketChannel.read(buffer);
socket = socketChannel.socket();
if (numBytes == -1) {
key.cancel();
closeSocket(socket);
}
else {
String chatName = null;
byte[] byteArray = buffer.array();
if (byteArray[0] == '#')
announceNewUser(socketChannel, buffer);
else {
for (ChatUser chatUser : allUsers)
if (chatUser.getUserSocketChannel().equals(socketChannel))
chatName = chatUser.getChatName();
broadcastMessage(chatName, buffer);
}
}
}
private static void closeSocket (Socket socket) {
try {
if (socket != null)
socket.close();
}
catch (IOException ioEx) {
System.out.println("Unable to close socket!");
}
}
public static void announceNewUser (SocketChannel userSocketChannel, ByteBuffer buffer) {
ChatUser chatUser;
byte[] byteArray = buffer.array();
int messageSize = buffer.position();
String chatName = new String(byteArray, 1, messageSize);
if (chatName.indexOf("\n") >= 0)
chatName = chatName.substring(0, chatName.indexOf("\n"));
chatUser = new ChatUser(userSocketChannel, chatName);
allUsers.add(chatUser);
if (!socketChannelVec.remove(userSocketChannel)) {
System.out.println("Can't find user!");
return;
} // we should save userSocketChannel in a chatUser instance before deleting it.
chatName = chatUser.getChatName();
System.out.println(chatName + " entered the chat room at " + new Date() + "." + NEW_LINE);
String welcomeMessage = "Welcome " + chatName + "!" + NEW_LINE;
byte[] bytes = welcomeMessage.getBytes();
buffer.clear();
for (int i = 0; i < welcomeMessage.length(); i++)
buffer.put(bytes[i]);
buffer.flip();
try {
chatUser.getUserSocketChannel().write(buffer);
}
catch (IOException ioEx) {
ioEx.printStackTrace();
}
}
public static void announceExit (String name) {
System.out.println(name + " left chat room at " + new Date() + "." + NEW_LINE);
for (ChatUser chatUser : allUsers) {
if (chatUser.getChatName().equals(name))
allUsers.remove(chatUser);
}
}
public static void broadcastMessage (String chatName, ByteBuffer buffer) {
String messagePrefix = chatName + ": ";
byte[] messagePrefixBytes = messagePrefix.getBytes();
final byte[] CR = NEW_LINE.getBytes();
try {
int messageSize = buffer.position();
byte[] messageBytes = buffer.array();
byte[] messageBytesCopy = new byte[messageSize];
String userMessage = new String(messageBytes, 0, messageSize);
if (userMessage.equals("Bye"))
announceExit(chatName);
for (int i = 0; i < messageSize; i++)
messageBytesCopy[i] = messageBytes[i];
buffer.clear();
buffer.put(messagePrefixBytes);
for (int i = 0; i < messageSize; i++)
buffer.put(messageBytesCopy[i]);
buffer.put(CR);
SocketChannel chatSocketChannel;
for (ChatUser chatUser : allUsers) {
chatSocketChannel = chatUser.getUserSocketChannel();
buffer.flip();
chatSocketChannel.write(buffer);
}
}
catch (IOException ioEx) {
ioEx.printStackTrace();
}
}
}
class ChatUser {
private SocketChannel userSocketChannel;
private String chatName;
public ChatUser (SocketChannel userSocketChannel, String chatName) {
this.userSocketChannel = userSocketChannel;
this.chatName = chatName;
}
public SocketChannel getUserSocketChannel () {
return userSocketChannel;
}
public String getChatName () {
return chatName;
}
}
// Code for a chat client for testing purpose
package multithreadEchoChatroomClientGUI;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.net.*;
import java.util.*;
public class MultithreadEchoChatroomClient1 {
private static Socket socket;
private static InetAddress host;
private static String address;
public static final int PORT = 1234;
public static void main(String[] args) {
address = JOptionPane.showInputDialog("Enter the host name or IP address:");
try {
host = InetAddress.getByName(address);
}
catch (UnknownHostException uhEx) {
JOptionPane.showMessageDialog(null, "Unknown Host!", "Error", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
try {
socket = new Socket(host, PORT);
}
catch (IOException ioEx) {
JOptionPane.showMessageDialog(null, ioEx.toString(), "Error", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
SwingUtilities.invokeLater(new Runnable () {
public void run () {
ClientFrame client = new ClientFrame(host, socket, address);
client.setTitle("Chat");
client.setSize(400, 500);
client.setVisible(true);
new Thread(client).start();
}
});
}
}
class ClientFrame extends JFrame implements Runnable {
private InetAddress host;
private String address;
private Socket socket;
private Scanner input;
private PrintWriter output;
private JMenuItem connect;
private JTextArea serverResponseArea;
private JTextArea messageArea;
private JTextField messageFiled;
private JButton sendButton;
private String serverResponse;
private String clientName;
public ClientFrame (InetAddress host, Socket socket, String address) {
this.host = host;
this.socket = socket;
this.address = address;
initFrame();
}
public void run () {
try {
input = new Scanner(socket.getInputStream());
output = new PrintWriter(socket.getOutputStream(), true);
}
catch (IOException ioEx) {
JOptionPane.showMessageDialog(this, "Cannot create input or output stream!", "Error", JOptionPane.ERROR_MESSAGE);
closeSocket();
System.exit(1);
}
do {
clientName = JOptionPane.showInputDialog("What nickname would you like to use in the chatroom?");
} while (clientName == null);
output.println("#" + clientName);
do {
serverResponse = input.nextLine();
serverResponseArea.append(serverResponse + "\n");
} while (socket.isClosed() != true);
}
private final void closeSocket () {
try {
socket.close();
}
catch (IOException ioEx) {
JOptionPane.showMessageDialog(this, "Cannot disconnect from chatroom!", "Error", JOptionPane.ERROR_MESSAGE);
}
}
private void initFrame () {
JMenuBar menuBar = createMenuBar();
setJMenuBar(menuBar);
JScrollPane responsePanel = createResponsePanel();
add(responsePanel, BorderLayout.NORTH);
JPanel messagePanel = createMessagePanel();
add(messagePanel, BorderLayout.CENTER);
//JPanel textPanel = createTextPanel();
//add(textPanel, BorderLayout.SOUTH);
addWindowListener(new WindowAdapter () {
#Override
public void windowClosing (WindowEvent we) {
if (!socket.isClosed())
closeSocket();
System.exit(0);
}
});
}
private JMenuBar createMenuBar () {
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Operations");
connect = new JMenuItem("Connect");
connect.setEnabled(false);
connect.addActionListener(new ActionListener () {
#Override
public void actionPerformed (ActionEvent event) {
try {
host = InetAddress.getByName(address);
}
catch (UnknownHostException uhEx) {
JOptionPane.showMessageDialog(null, "Unknown Host!", "Error", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
try {
socket = new Socket(host, MultithreadEchoChatroomClient1.PORT);
}
catch (IOException ioEx) {
JOptionPane.showMessageDialog(null, ioEx.toString(), "Error", JOptionPane.ERROR_MESSAGE);
}
try {
input = new Scanner(socket.getInputStream());
output = new PrintWriter(socket.getOutputStream(), true);
}
catch (IOException ioEx) {
JOptionPane.showMessageDialog(ClientFrame.this, "Cannot create input or output stream!", "Error", JOptionPane.ERROR_MESSAGE);
closeSocket();
System.exit(1);
}
output.println("#" + clientName);
serverResponse = input.nextLine();
serverResponseArea.append(serverResponse + "\n");
}
});
JMenuItem quit = new JMenuItem("Quit");
quit.addActionListener(new ActionListener() {
#Override
public void actionPerformed (ActionEvent event) {
if (!socket.isClosed())
closeSocket();
System.exit(0);
}
});
menu.add(connect);
menu.add(quit);
menuBar.add(menu);
return menuBar;
}
private JScrollPane createResponsePanel () {
serverResponseArea = new JTextArea(20, 35);
serverResponseArea.setEditable(false);
serverResponseArea.setLineWrap(true);
serverResponseArea.setWrapStyleWord(true);
serverResponseArea.setMargin(new Insets(5, 5, 5, 5));
JScrollPane scrlPane = new JScrollPane(serverResponseArea);
scrlPane.setBorder(BorderFactory.createEmptyBorder(20, 10, 10, 20));
scrlPane.setBackground(Color.yellow);
return scrlPane;
}
private JPanel createMessagePanel () {
JPanel msgPanel = new JPanel();
msgPanel.setBorder(BorderFactory.createEmptyBorder(20,10, 10, 20));
msgPanel.setBackground(Color.blue);
msgPanel.setLayout(new BoxLayout(msgPanel, BoxLayout.LINE_AXIS));
JScrollPane srlPanel = createMessageTextPanel();
msgPanel.add(srlPanel);
JButton sdButton = createSendButton();
msgPanel.add(sdButton);
return msgPanel;
}
private JScrollPane createMessageTextPanel () {
messageArea = new JTextArea(10, 35);
//messageArea.setEditable(false);
messageArea.setLineWrap(true);
messageArea.setWrapStyleWord(true);
messageArea.setMargin(new Insets(5, 5, 5, 5));
JScrollPane mtPanel = new JScrollPane(messageArea);
return mtPanel;
}
private JButton createSendButton () {
JButton button = new JButton("Send");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed (ActionEvent event) {
String message;
message = messageArea.getText();
System.out.println(message);
output.println(message);
if (message.equals("Bye")) {
closeSocket();
connect.setEnabled(true);
}
messageArea.setText("");
//serverResponse = input.nextLine();
//serverResponseArea.append(serverResponse + "\n");
}
});
return button;
}
}
Thank you again for taking so much trouble reading much code and giving suggestions!
The problem is solved according to #user207421. I should have put a remove() operation in the else {} block in the method acceptData(SelectedKey key) so that the old key associated with the socketChannel is removed from the selected key set for new incoming keys to be able to be detected.
I don't know whether my understanding of user207421's solution was right or not, but it did solve the problem for now. If anybody has any other ideas, please share your views.
Thank you again, user207421. And thank all visitors to this post for your attention.
This question already has an answer here:
GUI freeze after click on button
(1 answer)
Closed 6 years ago.
im creating a client/server program. Clients need to connect to a server that is connected to a interface and every 5 min clients send a String that will be showed in the server's inteface.
This is the Server Interface code:
public class MainServer implements ActionListener {
public static JFrame f_principale;
JButton avvio_server;
JButton ferma_server;
public static JLabel risultato;
JButton richiesta;
Server server;
public static JTextArea ritorni;
public MainServer(){
UI_LOADER();
}
public void BUTTON_LOADER(){
avvio_server = new JButton("Avvia");
ferma_server = new JButton("Ferma");
richiesta = new JButton("Richiedi");
avvio_server.addActionListener(this);
ferma_server.addActionListener(this);
richiesta.addActionListener(this);
}
public void TEXT_LOADER(){
risultato = new JLabel();
risultato.setText("prova");
ritorni = new JTextArea();
}
public void WINDOW_LOADER(){
f_principale = new JFrame("Centro Meteorologica");
f_principale.setSize(800, 600);
f_principale.setVisible(true);
f_principale.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f_principale.setBackground(Color.gray);
f_principale.add(avvio_server);
f_principale.add(ferma_server);
f_principale.add(richiesta);
f_principale.add(ritorni);
f_principale.add(risultato);
avvio_server.setBounds(100, 400, 200, 100);
ferma_server.setBounds(500, 400, 200, 100);
richiesta.setBounds(350, 400, 100, 50);
ritorni.setBounds(100, 50, 600, 300);
risultato.setBounds(300, 530, 200, 50);
}
public void UI_LOADER(){
BUTTON_LOADER();
TEXT_LOADER();
WINDOW_LOADER();
}
public static void main(String[] args) {
MainServer m1 = new MainServer();
}
#Override
public void actionPerformed(ActionEvent e) {
JButton button = (JButton)e.getSource();
if(button.getText() == "Avvia"){
System.out.print("Server avviato");
Thread server = new Server();
System.out.print("Server avviato");
server.run();
System.out.print("Server avviato");
}
if(button.getText() == "Ferma"){
try {
server.closeServer();
} catch (IOException e1) {
e1.printStackTrace();
}
}
if(button.getText() == "Richiedi"){
}
}
And this is the Server code:
public class Server extends Thread{
private ServerSocket serverSocket;
int clientPort;
ArrayList clients = new ArrayList();
public void run(){
Socket client;
try {
MainServer.ritorni.setText("Server Aperto");
serverSocket= new ServerSocket(4500);
System.out.println("Server Aperto");
} catch (IOException e) {
MainServer.risultato.setText("Errore nel aprire il server");
}
while(true){
client = null;
try {
client=serverSocket.accept();
MainServer.risultato.setText("Dispositivo collegato");
} catch (IOException e) {
MainServer.risultato.setText("Errore nel collegare il dispositivo");
}
clients.add(client);
Thread t=new Thread(new AscoltoDispositivo(client));
t.start();
}
}
public void closeServer() throws IOException{
serverSocket.close();
}
public void broadcastMessage(BufferedReader is, DataOutputStream os, Socket client) throws IOException{
for(Iterator all=clients.iterator();all.hasNext();){
Socket cl=(Socket)all.next();
sendMessage(cl);
}
}
private void sendMessage(Socket cl) throws IOException{
new DataOutputStream(cl.getOutputStream()).writeBytes("ASKRESPONSE");
}
}
class AscoltoDispositivo implements Runnable{
DataOutputStream os;
BufferedReader is;
Socket client;
static String tempReceived = null;
public AscoltoDispositivo(Socket client){
this.client=client;
try{
is= new BufferedReader(new InputStreamReader(client.getInputStream()));
os= new DataOutputStream (client.getOutputStream());
}catch(IOException e){
e.printStackTrace();
}
}
#Override
public void run() {
while(true){
try {
tempReceived = is.readLine();
MainServer.ritorni.append(tempReceived);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
my only problem is that the interface get freezed after i click the start button.
You have your Server running on the UI thread:
if(button.getText() == "Avvia"){
System.out.print("Server avviato");
Thread server = new Server();
System.out.print("Server avviato");
server.start(); // <- not run()
System.out.print("Server avviato");
}
I have a client-server communication code. but, I actually want multiple clients communicating with the server not other clients, how should I implement it?
// This is server code:
import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class ServerFile extends JFrame {
private JTextField usertext;
private JTextArea chatwindow;
private ObjectOutputStream output;
private ObjectInputStream input;
private ServerSocket server;
private Socket connection;
public ServerFile() {
super("Admin");
usertext = new JTextField();
usertext.setEditable(false);
usertext.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
sendmessage(event.getActionCommand());
usertext.setText("");
}
});
add(usertext, BorderLayout.SOUTH);
chatwindow = new JTextArea();
add(new JScrollPane(chatwindow));
setSize(300, 250);
setVisible(true);
}
public void startrunning() {
try {
server = new ServerSocket(6789, 100);
while (true) {
try {
waitForConnection();
setupstream();
whilechatting();
} catch (Exception e) {
System.out
.println("\nYou have an error in conversation with client");
} finally {
closecrap();
}
}
} catch (Exception e) {
System.out.println("\nYou have an error in connecting with client");
}
}
private void waitForConnection() throws IOException {
showmessage("\nWaiting for someone to connect");
connection = server.accept();
showmessage("\nNow connected to "
+ connection.getInetAddress().getHostName());
}
private void setupstream() throws IOException {
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
showmessage("\nStreams are setup");
}
private void whilechatting() throws IOException {
String message = "\nYou are now connected ";
sendmessage(message);
ableToType(true);
do {
try {
message = (String) input.readObject();
showmessage(message);
} catch (Exception e) {
System.out.println("\nError in reading message");
}
} while (!message.equals("CLIENT-END"));
}
private void closecrap() {
showmessage("\nClosing connection");
ableToType(false);
try {
output.close();
input.close();
connection.close();
} catch (Exception e) {
System.out.println("\nError in closing server");
}
}
private void sendmessage(String message) {
try {
chatwindow.append("\nSERVER: " + message);
output.writeObject("\nSERVER: " + message);
output.flush();
} catch (Exception e) {
chatwindow.append("\nError in sending message from server side");
}
}
private void showmessage(final String text) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
chatwindow.append("\n" + text);
}
});
}
private void ableToType(final boolean tof) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
usertext.setEditable(tof);
}
});
}
}
public class Server {
public static void main(String args[]) {
ServerFile server1 = new ServerFile();
server1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
server1.startrunning();
}
}
// and this is the client code:
import javax.swing.JFrame;
import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class ClientFile extends JFrame {
private static final long serialVersionUID = 1L;
private JTextField usertext;
private JTextArea chatwindow;
private ObjectOutputStream output;
private ObjectInputStream input;
private String message="";
private String serverIP;
private ServerSocket server;
private Socket connection;
public ClientFile(String host)
{
super("Client");
serverIP=host;
usertext= new JTextField();
usertext.setEditable(false);
usertext.addActionListener( new ActionListener(){
public void actionPerformed(ActionEvent event){
sendmessage(event.getActionCommand());
usertext.setText("");
}
}
);
add(usertext,BorderLayout.SOUTH);
chatwindow= new JTextArea();
add(new JScrollPane(chatwindow));
setSize(300,250);
setVisible(true);
}
public void startrunning() {
try {
connecttoserver();
setupstream();
whilechatting();
}
catch(Exception e){
System.out.println("\nYou have an error in coversation with server");
}
finally{
closecrap();
}
}
private void connecttoserver() throws IOException{
showmessage("\nAttempting connection");
connection = new Socket(InetAddress.getByName("127.0.0.1"),6789);
showmessage("\nConnected to "+connection.getInetAddress().getHostName());
}
private void setupstream() throws IOException{
output= new ObjectOutputStream(connection.getOutputStream());
output.flush();
input= new ObjectInputStream(connection.getInputStream());
showmessage("\nStreams are good to go");
}
private void whilechatting()throws IOException{
ableToType(true);
do {
try{
message = (String)input.readObject();
showmessage(message);
}
catch(Exception e){
System.out.println("\nError in writing message");
}
} while(!message.equals("SERVER - END"));
}
private void closecrap(){
showmessage("\nClosing....");
ableToType(false);
try{
output.close();
input.close();
connection.close();
}
catch(Exception e){
System.out.println("\nError in closing client");
}
}
private void sendmessage(String message){
try{
chatwindow.append("\nCLIENT: "+message);
output.writeObject("\nCLIENT: "+message);
output.flush();
}
catch(Exception e){
chatwindow.append("\nError in sending message from client side");
}
}
private void showmessage(final String m){
SwingUtilities.invokeLater( new Runnable(){
public void run(){
chatwindow.append("\n"+m);
}});
}
private void ableToType(final boolean tof){
SwingUtilities.invokeLater( new Runnable(){
public void run(){
usertext.setEditable(tof);
}});
}
}
public class Client {
public static void main(String args[])
{
ClientFile obj2= new ClientFile("127.0.0.1");
obj2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
obj2.startrunning();
}
}
Applying multithreading is a good solution, but when I applied, there gets connection extablished between only one client and one server.. Please help me to do this
Applying multithreading is a good solution, but when I applied, there gets connection extablished between only one client and one server.. Please help me to do this
I did not get through (and thus checked) all your code, but I noticed one thing:
in your startrunning() function you:
create a server socket
in an infine loop:
wait for a new connection
when there's a new connection call setupstream()
and chat using whilechatting()
so there, you will get only one new connection that will get its stream set up and chat. You can only have one thread serving your clients, so only the first one arrived will get served, until it releases the thread so another can connect.
You should instead do:
create a server socket
in an infine loop:
wait for a new connection
when there's a new connection:
create a new thread for that connection
call setupstream()
and chat using whilechatting()
There each client will get spawned into their own cosy thread, while the main thread is in its infinite loop waiting for new clients.
HTH
I'm working on the client side application of the client/server chat I'm doing for learning experience. My problem is I can't seem to get the socket and swing,both to run at the same time.
What I want to is, when the user opens a JOpionsPane and enters the hostname and port number, clicks okay, then they are connected. When the socket information was hardcoded it worked fine, but now I'm trying to get the users input for it.
What's meant to happen is, action listener is supposed to create the new SocketManager object that handles communication. Event though it says it's connected, it doesn't run. When I create the new SocketManager object and run it on a new thread it connects and revives messages form the server, but then the swings freezes and I have to end the process to shut it down.
Should I start it on a new worker thread or something? Maybe it's just because I'm tired, but I'm out of ideas.
EDIT
I updated my ActLis.class and SocketManager.class with the suggestion of adding a new thread for my SocketManager object 'network'. When I try and use 'network' though it returns null for some reason.
ActLis.clss
package com.client.core;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
public class ActLis implements ActionListener {
private Main main = new Main();;
private JTextField ipadress = new JTextField(),
portnumber = new JTextField(),
actionField;
private String username;
final JComponent[] ipinp = new JComponent[]{new JLabel("Enter Hostname (IP Adress): "),
ipadress,
new JLabel("Enter Port number: "), portnumber};
private SocketManager network;
private Window win;
public ActLis(){
}
public ActLis(JTextField t, Window w){
actionField = t;
win = w;
}
#Override
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
if(cmd == "Exit"){
System.exit(0);
} else if(cmd == "Connect to IP"){
try{
JOptionPane.showMessageDialog(null, ipinp, "Connect to IP", JOptionPane.PLAIN_MESSAGE);
if(network != null){
network.close();
}
network = new SocketManager(ipadress.getText(),Integer.parseInt(portnumber.getText()));
network.setGUI(win);
Thread t = new Thread(network);
t.start();
JOptionPane.showMessageDialog(null, "Connected to chat host successfully!","Connected", JOptionPane.INFORMATION_MESSAGE);
}catch(Exception ee){
JOptionPane.showMessageDialog(null, "Could not connect. Check IP adress or internet connection","Error - Could not connect", JOptionPane.ERROR_MESSAGE);
ee.printStackTrace();
}
} else if (cmd == "chatWriter"){
if( actionField.getText() != ""){
try{
network.send(actionField.getText());
win.updateChat(actionField.getText());
actionField.setText("");
actionField.requestFocus();
}catch(Exception ex){
JOptionPane.showMessageDialog(null, "You are not connected to a host. (File -> Connect to IP)","Error - Not Connected", JOptionPane.ERROR_MESSAGE);
ex.printStackTrace();
}
}
} else if (cmd == "setUsername"){
username = actionField.getText();
network.send("USERNAME:" + username);
}
}
}
Main.class
package com.client.core;
import javax.swing.JFrame;
public class Main extends JFrame{
private SocketManager network;
public static void main(String[] args){
Main main = new Main();
main.run();
}
private void run(){
Window win = new Window();
win.setVisible(true);
}
}
SocketManager.class
package com.client.core;
import java.io.*;
import java.net.*;
public class SocketManager implements Runnable {
private Socket sock;
private PrintWriter output;
private BufferedReader input;
private String hostname;
private int portnumber;
private String message;
private Window gui;
public SocketManager(String ip, int port){
try{
hostname = ip;
portnumber = port;
}catch(Exception e){
System.out.println("Client: Socket failed to connect.");
}
}
public synchronized void send(String data){
try{
//System.out.println("Attempting to send: " + data);
output.println(data);
output.flush();
//System.out.println("Message sent.");
}catch(Exception e){
System.out.println("Message could not send.");
}
}
public synchronized void setGUI(Window w){
gui = w;
}
public synchronized void connect(){
try{
sock = new Socket(hostname,portnumber);
}catch(Exception e){
}
}
public synchronized Socket getSocket(){
return sock;
}
public synchronized void setSocket(SocketManager s){
sock = s.getSocket();
}
public synchronized void close(){
try{
sock.close();
}catch(Exception e){
System.out.println("Could not close connection.");
}
output = null;
input = null;
System.gc();
}
public synchronized boolean isConnected(){
return (sock == null) ? false : (sock.isConnected() && !sock.isClosed());
}
public synchronized void listenStream(){
try {
while((message = input.readLine()) != null){
System.out.println("Server: " + message);
gui.updateChat(message);
}
} catch (Exception e) {
}
}
#Override
public void run() {
try {
sock = new Socket(hostname,portnumber);
output = new PrintWriter(sock.getOutputStream(),true);
input = new BufferedReader(
new InputStreamReader(sock.getInputStream()));
while(true){
listenStream();
}
} catch (Exception e) {
System.out.println("Run method fail. -> SocketManager.run()");
}finally{
try {
sock.close();
} catch (Exception e) {
}
}
}
}
Window.class
package com.client.core;
import java.awt.*;
import javax.swing.*;
public class Window extends JFrame{
private int screenWidth = 800;
private int screenHeight = 600;
private SocketManager network;
private JPanel window = new JPanel(new BorderLayout()),
center = new JPanel(new BorderLayout()),
right = new JPanel(new BorderLayout()),
display = new JPanel( new BorderLayout()),
chat = new JPanel(),
users = new JPanel(new BorderLayout());
private JTextArea chatBox = new JTextArea("Welcome to the chat!", 7,50),
listOfUsers = new JTextArea("None Online");
private JTextField chatWrite = new JTextField(),
userSearch = new JTextField(10),
username = new JTextField();
private JScrollPane userList = new JScrollPane(listOfUsers),
currentChat = new JScrollPane(chatBox);
private JMenuBar menu = new JMenuBar();
private JMenu file = new JMenu("File");
private JMenuItem exit = new JMenuItem("Exit"),
ipconnect = new JMenuItem("Connect to IP");
private JComponent[] login = new JComponent[]{new JLabel("Username:"), username};
public Window(){
//Initial Setup
super("NAMEHERE - Chat Client Alpha v0.0.1");
setResizable(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(screenWidth,screenHeight);
//Panels
listOfUsers.setLineWrap(true);
listOfUsers.setEditable(false);
display.setBackground(Color.black);
chat.setLayout(new BoxLayout(chat, BoxLayout.Y_AXIS));
chat.setBackground(Color.blue);
users.setBackground(Color.green);
//TextFields
addChatArea();
//Menu bar
addMenuBar();
//Adding the main panels.
addPanels();
//Listeners
addListeners();
for(int x = 0; x < 1; x++){
login();
}
}
private void login(){
JOptionPane.showMessageDialog(null, login, "Log in", JOptionPane.PLAIN_MESSAGE);
}
private void addChatArea(){
chatBox.setEditable(false);
userList.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
currentChat.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
users.add(userList);
users.add(userSearch, BorderLayout.NORTH);
chat.add(currentChat);
chat.add(chatWrite);
chat.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
}
private void addMenuBar(){
file.add(ipconnect);
file.add(exit);
menu.add(file);
}
private void addPanels(){
right.add(users);
center.add(display, BorderLayout.CENTER);
center.add(chat, BorderLayout.SOUTH);
window.add(center, BorderLayout.CENTER);
window.add(right, BorderLayout.EAST);
window.add(menu, BorderLayout.NORTH);
add(window);
}
private void addListeners(){
username.addActionListener(new ActLis(username, this));
chatWrite.addActionListener(new ActLis(chatWrite, this));
username.setActionCommand("setUsername");
chatWrite.setActionCommand("chatWriter");
ipconnect.addActionListener(new ActLis());
exit.addActionListener(new ActLis());
}
public void setNetwork(SocketManager n){
network = n;
}
public void updateChat(String s){
chatBox.setText(chatBox.getText() + "\n" + s);
}
}
Ok #Zexanima you have create a Socket class for socket manager. Something like this:
public class YouSocketClass {
static public Socket socket = null;
static public InputStream in = null;
static public OutputStream out = null;
public YouSocketClass() {
super();
}
public static final Socket getConnection(final String ip, final int port, final int timeout) {
try {
socket = new Socket(ip, port);
try {
socket.setSoTimeout(timeout);
} catch(SocketException se) {
log("Server Timeout");
}
in = socket.getInputStream();
out = socket.getOutputStream();
} catch(ConnectException e) {
log("Server name or server ip is failed. " + e.getMessage());
e.printStackTrace();
} catch(Exception e) {
log("ERROR Socket: " + e.getMessage() + " " + e.getCause());
e.printStackTrace();
}
return socket;
}
public static void closeConnection() {
try {
if(socket != null) {
if(in != null) {
if(out != null) {
socket.close();
in.close();
out.close();
}
}
}
} catch(Exception e2) {
e2.printStackTrace();
}
}
private static Object log(Object sms) {
System.out.println("Test Socket1.0: " + sms);
return sms;
}
}
I hope that serve. :)