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();
}
}
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...
}
}
}
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