2
votes

I coded a basic isnatnt messager program, but it only lets oone client connect to the server. What would I change in my code so it would accept multiple clients, not have them wait in a line.

Client.java

import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.Color;
import java.awt.Font; 

public class Client extends JFrame{

   private JTextField userText;
   private JTextArea chatWindow;
   private ObjectOutputStream output;
   private ObjectInputStream input;
   private String message = "";
   private String serverIP;
   private Socket connection;
   private JTextField UsernameField;
   private String Username;
   Color RED = new Color(255,0,0);
   Color ORANGE = new Color(255,128,0);
   Color YELLOW = new Color(255,255,0);
   Color LIGHT_GREEN = new Color(51,255,51);
   Color GREEN = new Color(0,255,0);
   Color DARK_GREEN = new Color(0,102,0);
   Color LIGHT_BLUE = new Color(51,51,255);
   Color BLUE = new Color(0,0,255);
   Color DARK_BLUE = new Color(0,0,102);
   Color PURPLE = new Color(153,0,153);



   //constructor
   public Client(String host){
      super("Azrin IM");
      serverIP = host;

      userText = new JTextField("Enter Message Here.");
      userText.addMouseListener(new MouseAdapter() {
          public void mouseClicked(MouseEvent e) {
              if (userText.getText().equals("Enter Message Here.")) // User has not entered text yet
                  userText.setText("");
          }
      });



      userText.setEditable(true);
      UsernameField = new JTextField("Enter Username Here.");
      UsernameField.addMouseListener(new MouseAdapter() {
          public void mouseClicked(MouseEvent e) {
              if (UsernameField.getText().equals("Enter Username Here.")) // User has not entered text yet
                  UsernameField.setText("");
          }
      });

      add(new JLabel ("Enter Username Here."));
      UsernameField.setEditable(true);
      userText.addActionListener(
         new ActionListener(){
            public void actionPerformed(ActionEvent event){
                Username = UsernameField.getText();
                sendMessage(event.getActionCommand());
                userText.setText("");
                UsernameField.setText("");
            }
         }
      );
      add(userText, BorderLayout.SOUTH);
      add (UsernameField, BorderLayout.NORTH);
      chatWindow = new JTextArea();
      add(new JScrollPane(chatWindow), BorderLayout.CENTER);
      setSize(400,300);
      setVisible(true);
   }


   //connect to server
   public void startRunning(){
      try{
         connectToServer();
         setupStreams();
         whileChatting();
      }catch(EOFException eofException){
         showMessage("\n Client terminated connection");
      }catch(IOException ioException){
         ioException.printStackTrace();
      }finally{
         Disconnect();
      }
   }

   //connect to server
   private void connectToServer() throws IOException{
      showMessage("Attempting connection... \n");
      connection = new Socket(InetAddress.getByName(serverIP), 6969);
      showMessage("Connected to: " + connection.getInetAddress().getHostName() );
   }

   //set up streams to send and receive messages
   private void setupStreams() throws IOException{
      output = new ObjectOutputStream(connection.getOutputStream());
      output.flush();
      input = new ObjectInputStream(connection.getInputStream());
      showMessage("\n Now connected to Server! \n");
   }

   //while chatting with server
   private void whileChatting() throws IOException{
      ableToType(true);
      do{
         try{
            message = (String) input.readObject();
            showMessage("\n" + message);
         }catch(ClassNotFoundException classNotfoundException){
            showMessage("\n I dont know that object type");
         }
      }while(!message.equals(Username + ": END"));



   }



   //close the streams and sockets
   private void Disconnect(){
      showMessage("\n Disconnected.");
      ableToType(false);
      try{
         output.close();
         input.close();
         connection.close();
      }catch(IOException ioException){
         ioException.printStackTrace();
      }
   }

   //send messages to server
   private void sendMessage(String message){
      try{
         output.writeObject(Username + ": " + message);
         output.flush();
         showMessage("\n" + Username + ": " + message);
         if (message.equals("RED")){
          chatWindow.setForeground(RED);
         }
         if (message.equals("ORANGE")){
              chatWindow.setForeground(ORANGE);
            }
         if (message.equals("YELLOW")){
               chatWindow.setForeground(YELLOW);
           }
         // I am aware I need to space these if staments better :) .
if (message.equals("LIGHT_GREEN")){
     chatWindow.setForeground(LIGHT_GREEN);
 }
if (message.equals("GREEN")){
     chatWindow.setForeground(GREEN);
}
if (message.equals("DARK_GREEN")){
     chatWindow.setForeground(DARK_GREEN);
}
if (message.equals("LIGHT_BLUE")){
     chatWindow.setForeground(LIGHT_BLUE);
}
if (message.equals("BLUE")){
     chatWindow.setForeground(BLUE);
}
if (message.equals("DARK_BLUE")){
     chatWindow.setForeground(DARK_BLUE);
}
if (message.equals("PURPLE")){
     chatWindow.setForeground(PURPLE);
}



      }catch(IOException ioException){
         chatWindow.append("\n something messed up sending message hoss!");
      }
   }

   //change/update chatWindow
   private void showMessage(final String m){
      SwingUtilities.invokeLater(
         new Runnable(){
            public void run(){
               chatWindow.append(m);
            }
         }
      );
   }

   //gives user permission to type crap into the text box
   private void ableToType(final boolean tof){
      SwingUtilities.invokeLater(
         new Runnable(){
            public void run(){
               userText.setEditable(tof);
            }
         }
      );      
   }
}

ClientTest.java

import javax.swing.JFrame;

public class ClientTest {
   public static void main(String[] args) {
      Client charlie;
      charlie = new Client("69.125.13.88");
      charlie.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      charlie.startRunning();
   }
}

Server.java

import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Server extends JFrame{

   private JTextField userText;
   private JTextArea chatWindow;
   private ObjectOutputStream output;
   private ObjectInputStream input;
   private ServerSocket server;
   private Socket connection;

   //constructor
   public Server(){
      super("Azrin IM Server");
      userText = new JTextField();
      userText.setEditable(false);
      userText.addActionListener(
         new ActionListener(){
            public void actionPerformed(ActionEvent event){
               sendMessage(event.getActionCommand());
               userText.setText("");
            }
         }
      );
      add(userText, BorderLayout.NORTH);
      chatWindow = new JTextArea();
      add(new JScrollPane(chatWindow));
      setSize(500,200);
      setVisible(true);
   }

   //set up and run the server
   public void startRunning(){
      try{
         server = new ServerSocket(6969, 100);
         while(true){
            try{
               waitForConnection();
               setupStreams();
               whileChatting();
            }catch(EOFException eofException){
               showMessage("\n Server ended the connection! ");
            }finally{
               closeCrap();
            }
         }
      }catch(IOException ioException){
         ioException.printStackTrace();
      }
   }

 //wait for connection, then display connection information
   private void waitForConnection() throws IOException{
      showMessage(" Waiting for someone to connect... \n");
      connection = server.accept();
      showMessage(" Now connected to " + connection.getInetAddress().getHostName());
   }

   //get stream to send and receive data
   private void setupStreams() throws IOException{
      output = new ObjectOutputStream(connection.getOutputStream());
      output.flush();
      input = new ObjectInputStream(connection.getInputStream());
      showMessage("\n Streams are now setup! \n");
   }

   //during the chat conversation
   private void whileChatting() throws IOException{
      String message = " You are now connected! ";
      sendMessage(message);
      ableToType(true);
      do{
         try{
            message = (String) input.readObject();
            showMessage("\n" + message);
         }catch(ClassNotFoundException classNotFoundException){
            showMessage("\n idk wtf that user sent!");
         }
      }while(!message.equals("CLIENT - END"));
   }

   //close streams and sockets after you are done chatting
   private void closeCrap(){
      showMessage("\n Closing connections... \n");
      ableToType(false);
      try{
         output.close();
         input.close();
         connection.close();
      }catch(IOException ioException){
         ioException.printStackTrace();
      }
   }

   //send a message to client
   private void sendMessage(String message){
      try{
         output.writeObject("Josh A - " + message);
         output.flush();
         showMessage("\nSERVER - " + message);
      }catch(IOException ioException){
         chatWindow.append("\n ERROR: DUDE I CANT SEND THAT MESSAGE");
      }
   }

   //updates chatWindow
   private void showMessage(final String text){
      SwingUtilities.invokeLater(
         new Runnable(){
            public void run(){
               chatWindow.append(text);
            }
         }
      );
   }

   //let the user type stuff into their box
   private void ableToType(final boolean tof){
      SwingUtilities.invokeLater(
         new Runnable(){
            public void run(){
               userText.setEditable(tof);
            }
         }
      );
   }

}

ServerTest.java

import javax.swing.JFrame;

public class ServerTest {
   public static void main(String[] args) {
      Server sally = new Server();
      sally.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      sally.startRunning();
   }

}

1
This question has been asked 3 times in the last two days...Start with All about Sockets and Concurrency. You're going to need to understand these topics very well to proceed, so I suggest you start with some simple examples and work your way up...MadProgrammer
IK what sokcets are. IT said something about having to put serverTest.java in a form of a thread somwhere else. How would I do that?user2371981

1 Answers

4
votes

Plain Thread Example

This is "plain" thread example, is probably among the more common examples you might find. The problem with this is you can lose control of threads and have hundreds of ramped threads all running about, consuming system resources...

It is simple and does demonstrate the basic concept of what you need to achieve...

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class TestSocketThread {

    // Need away to stop the program...
    private static boolean acceptMore = true;

    public static void main(String[] args) {
        new TestSocketThread();
    }

    public TestSocketThread() {
        ServerSocket serverSocket = null;
        try {
             serverSocket = new ServerSocket(6969, 100);
            while (acceptMore) {
                Socket socket = serverSocket.accept();
                new Thread(new SocketThread(socket)).start();    
            }
        } catch (IOException exp) {
            exp.printStackTrace();
        } finally {
            try {
                serverSocket.close();
            } catch (Exception e) {
            }
        }
    }

    public class SocketThread implements Runnable {

        private Socket socket;

        public SocketThread(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            // Process socket...
        }
    }
}

Executor Service Example

The executor services are more flexible and provide better management control over plain threads, including (as per this example) a fixed thread pool.

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecutorSocketTest {

    // Need away to stop the program...
    private static boolean acceptMore = true;

    public static void main(String[] args) {
        new ExecutorSocketTest();
    }

    public ExecutorSocketTest() {
        ServerSocket serverSocket = null;
        ExecutorService executorService = Executors.newFixedThreadPool(100);
        try {
             serverSocket = new ServerSocket(6969, 100);
            while (acceptMore) {
                Socket socket = serverSocket.accept();
                executorService.submit(new SocketCallable(socket));
            }
        } catch (IOException exp) {
            exp.printStackTrace();
        } finally {
            try {
                serverSocket.close();
            } catch (Exception e) {
            }
            executorService.shutdownNow();
        }
    }

    /**
     *
     * @author swhitehead
     */
    public class SocketCallable implements Callable {

        private Socket socket;

        public SocketCallable(Socket socket) {
            this.socket = socket;
        }

        @Override
        public Object call() throws Exception {
            // Process socket requests...
            return null;
        }
    }
}

Your job is to now go away and read all about Concurrency in Java