Why cant both my client communicate to each other? (java server socket)

2.4k views Asked by At

i'm having trouble to connect TWO clients. is it bcoz i am using DataOutputStream and DataInputStream instead of BufferedReader and PrintWritter? For some reason, it just dont connect to each other even if i set the server sockets and sockets to be interconnected through localhost and port 8000.

i could not send messages between these two clients. But, yes, they can connect to the server. However, I want my clients to communicate each other instead so that it works like an online chat.

Server Side:

import java.io.*;
import java.net.*;
import java.util.*;
import java.awt.*;

import javax.swing.*;

public class Server extends JFrame {
// Text area for displaying contents
private static JTextArea jta = new JTextArea();


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

public Server() {

    setLayout(new BorderLayout());
    add(new JScrollPane(jta), BorderLayout.CENTER);

    setTitle("Server");
    setSize(500, 300);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true); // It is necessary to show the frame here!

    // Place text area on the frame
    try {
    // Create a server socket
    ServerSocket serverSocket = new ServerSocket(8000);
    jta.append("Server started at " + new Date() + '\n');
    try {
        while (true) {
            new Handler(serverSocket.accept()).start();
        }
    } finally {
        serverSocket.close();
    }

}
catch(IOException ex) {
    System.err.println(ex);
    }
}

public static class Handler extends Thread{

    Socket socket;
    DataInputStream inputFromClient;
    DataOutputStream outputToClient;

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

    public void run(){
        // Listen for a connection request
          //Socket socket = serverSocket.accept();
          try{
        // Create data input and output streams
           inputFromClient = new DataInputStream(socket.getInputStream());
           outputToClient = new DataOutputStream(socket.getOutputStream());

            while (true) {

            // Receive data from the client
            String message =inputFromClient.readUTF();

            System.out.println("Server: Receive input");

            jta.append("Word received from client: " + message + '\n');


            // DO converting process
            //String newMessage ="";
            //newMessage= message.toUpperCase();
            // Send data back to the client
            outputToClient.writeUTF(message);
            //jta.append("Word Converted: " + newMessage + '\n');

            }
          }catch(IOException ex) {
            System.err.println(ex);
            }
        } 
    }
}

Client side

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

public class Client extends JFrame {
// Text field for receiving data
private JTextField jtf = new JTextField();
// Text area to display contents
private JTextArea jta = new JTextArea();
// IO streams
private  DataOutputStream toServer;
private  DataInputStream fromServer;

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

public Client() {
// Panel p to hold the label and text field
    JPanel p = new JPanel();
    p.setLayout(new BorderLayout());
    p.add(new JLabel("Enter word: "), BorderLayout.WEST);
    p.add(jtf, BorderLayout.CENTER);
    jtf.setHorizontalAlignment(JTextField.RIGHT);

    setLayout(new BorderLayout());
    add(p, BorderLayout.NORTH);
    add(new JScrollPane(jta), BorderLayout.CENTER);

    jtf.addActionListener(new Listener()); // Register listener

    setTitle("Client");
    setSize(500, 300);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true); // It is necessary to show the frame here!

    try {
    // Create a socket to connect to the server
     Socket socket = new Socket("localhost", 8000);
          // Socket socket = new Socket("130.254.204.36", 8000);
          // Socket socket = new Socket("drake.Armstrong.edu", 8000);

      // Create an input stream to receive data from the server
      fromServer = new DataInputStream(
        socket.getInputStream());

      // Create an output stream to send data to the server
      toServer =
        new DataOutputStream(socket.getOutputStream());


    }
    catch (IOException ex) {
    jta.append(ex.toString() + '\n');
    }
}

private class Listener implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        try {
        // Get the data from the text field
        String message = (jtf.getText().trim());

        // Send the data to the server
         toServer.writeUTF(message);

        // Get data from the server
         String serverMessage = fromServer.readUTF();
         System.out.println("from server");

        // Display to the text area

        jta.append("Word is " + message + "\n");
        jta.append("Word received from the server is "
          + serverMessage + '\n');
        toServer.flush();

        }
        catch (IOException ex) {
        System.err.println(ex);
        }
    }
}
}
2

There are 2 answers

3
Dawnkeeper On BEST ANSWER

Your software is not designed to handle client to client communication.

To achieve this you would have to:

  • store your client Handlers on the server (not throwing them away; use something dynamic like a LinkedList)
  • add a method to the Handler that allows to sent arbitrary messages to the Client this Handler represents
  • receive the client messages in a Handler
    • pass them to the server
    • send the message to the clients in the list using the sending method

I'm kind of 1999 "I can only show you the door. You're the one that has to walk through it." but SO seems to see this different today. So here we go.

Server:

import java.io.*;
import java.net.*;
import java.util.*;
import java.awt.*;

import javax.swing.*;

public class Server extends JFrame {
// Text area for displaying contents
private static JTextArea jta = new JTextArea();
LinkedList<Handler> handlers = new LinkedList<Handler>();

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

public void sendmessagetoall(String message)
{
    for(Handler current : handlers)
    {
        try
        {
            current.writeMessage(message);
        }
        catch (IOException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

public Server() {

    setLayout(new BorderLayout());
    add(new JScrollPane(jta), BorderLayout.CENTER);

    setTitle("Server");
    setSize(500, 300);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true); // It is necessary to show the frame here!

    // Place text area on the frame
    try {
    // Create a server socket
    ServerSocket serverSocket = new ServerSocket(8000);
    jta.append("Server started at " + new Date() + '\n');
    try {
        while (true) {
            Handler noob =  new Handler(serverSocket.accept(),this);
            handlers.add(noob);
            noob.start();
        }
    } finally {
        serverSocket.close();
    }

}
catch(IOException ex) {
    System.err.println(ex);
    }
}

public static class Handler extends Thread{

    Socket socket;
    Server parent;
    DataInputStream inputFromClient;
    DataOutputStream outputToClient;

    public Handler(Socket socket, Server parent){
        this.socket = socket;
        this.parent = parent;
    }

    public void writeMessage(String message) throws IOException
    {
        outputToClient.writeUTF(message);
    }

    public void run(){
        // Listen for a connection request
          //Socket socket = serverSocket.accept();
          try{
        // Create data input and output streams
           inputFromClient = new DataInputStream(socket.getInputStream());
           outputToClient = new DataOutputStream(socket.getOutputStream());

            while (true) {

            // Receive data from the client
            String message =inputFromClient.readUTF();

            System.out.println("Server: Receive input");

            jta.append("Word received from client: " + message + '\n');


            // DO converting process
            //String newMessage ="";
            //newMessage= message.toUpperCase();
            // Send data back to the client
            //writeMessage(message);
            parent.sendmessagetoall(message);
            //jta.append("Word Converted: " + newMessage + '\n');

            }
          }catch(IOException ex) {
            System.err.println(ex);
            }
        } 
    }
}

Client:

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

import javax.swing.*;

public class Client extends JFrame {
// Text field for receiving data
private JTextField jtf = new JTextField();
// Text area to display contents
private JTextArea jta = new JTextArea();
// IO streams
private  DataOutputStream toServer;
private  DataInputStream fromServer;

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

public Client() {
// Panel p to hold the label and text field
    JPanel p = new JPanel();
    p.setLayout(new BorderLayout());
    p.add(new JLabel("Enter word: "), BorderLayout.WEST);
    p.add(jtf, BorderLayout.CENTER);
    jtf.setHorizontalAlignment(JTextField.RIGHT);

    setLayout(new BorderLayout());
    add(p, BorderLayout.NORTH);
    add(new JScrollPane(jta), BorderLayout.CENTER);

    jtf.addActionListener(new Listener()); // Register listener

    setTitle("Client");
    setSize(500, 300);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true); // It is necessary to show the frame here!

    try {
    // Create a socket to connect to the server
     Socket socket = new Socket("localhost", 8000);
          // Socket socket = new Socket("130.254.204.36", 8000);
          // Socket socket = new Socket("drake.Armstrong.edu", 8000);

      // Create an input stream to receive data from the server
      fromServer = new DataInputStream(
        socket.getInputStream());

      // Create an output stream to send data to the server
      toServer =
        new DataOutputStream(socket.getOutputStream());

      new Thread(new Runnable(){

        @Override
        public void run()
        {
            while(true)
            {
                String serverMessage = "";
                try
                {
                    serverMessage = fromServer.readUTF();
                }
                catch (IOException e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                jta.append("Word received from the server is "
                          + serverMessage + '\n');
            }

        }})
        .start();


    }
    catch (IOException ex) {
    jta.append(ex.toString() + '\n');
    }
}

private class Listener implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        try {
        // Get the data from the text field
        String message = (jtf.getText().trim());

        // Send the data to the server
         toServer.writeUTF(message);

        // Get data from the server

         System.out.println("from server");

        // Display to the text area

        jta.append("Word is " + message + "\n");

        toServer.flush();

        }
        catch (IOException ex) {
        System.err.println(ex);
        }
    }
}
}

A quick and dirty edit to your code.
This doesn't handle Clients that dropped their connection and distributes the message to all clients, but you should get a starting point.

0
CODeeerrrrrrrr On

i have faced a lot of issues in java sockets and then got my way out:

just giving the server side code and a dummy client code using java sockets:

server

import java.net.ServerSocket;
import java.net.Socket;



public class SafeWalkServer {

    static public ServerSocket server;
    static public boolean runserver = true;
    static public List<Map.Entry<Socket,String>> clientRequests = new ArrayList<Map.Entry<Socket,String>>();

    public SafeWalkServer(int port) {

        try {
            server = new ServerSocket(port);
            server.setSoTimeout(0);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void startServer(){

        try {

            while(runserver){

                Socket client = server.accept();
                RequestHandler clientHandler = new RequestHandler(client);
                clientHandler.start();      
            }


        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    public static void main(String[] args){

            SafeWalkServer server = new SafeWalkServer(8080);
            server.startServer();
    }

}

then i have created a thread REQUEST HANDLER which contains the following code

public class RequestHandler extends Thread {


    private Socket client;

    public RequestHandler(Socket lclient) {
        client = lclient;
    }


    public void run(){      

        try {

            DataInputStream fromclient = getInputStream(client) ;           
            String clientinput = fromclient.readUTF();              

            //check if it is a request / command            
            if(clientinput.startsWith(":")){    

                processCommand(clientinput);    

            }else{

                processRequest(clientinput);
            }        

        } catch (Exception e) {

            e.printStackTrace();
        }           

    }


    private void processCommand(String clientinput){

        Iterator<Map.Entry<Socket,String>> listIter = SafeWalkServer.clientRequests.iterator();

        if(clientinput.equals(":LIST_PENDING_REQUESTS")){

            String allrequest = "List :";

            while(listIter.hasNext()){

                Map.Entry<Socket,String> clientrequest = listIter.next();
                Socket cclient = clientrequest.getKey();
                String crequest = clientrequest.getValue();
                allrequest = allrequest + "\n" + crequest;              
            }

            DataOutputStream tocclient = getOutputStream(client);
            try {
                tocclient.writeUTF(allrequest);
            } catch (Exception e) {

                e.printStackTrace();
            }


        }else if(clientinput.equals(":SHUTDOWN")){

            try {
                while(listIter.hasNext()){

                    Map.Entry<Socket,String> clientrequest = listIter.next();
                    Socket cclient = clientrequest.getKey();
                    String crequest = clientrequest.getValue();

                    DataOutputStream tocclient = getOutputStream(cclient);                  
                    tocclient.writeUTF("Shutdown : Server Shutting Down closing connection.");
                        //tocclient.close();
                }

                DataOutputStream tocclient = getOutputStream(client);                   
                tocclient.writeUTF("Shutdown : Server Shutting Down closing connection.");

                Thread.sleep(1000);

                SafeWalkServer.server.close();

                //SafeWalkServer.runserver = false ;

            } catch (Exception e) {

                e.printStackTrace();
            }           

        }
        else if(clientinput.equals(":RESET")){

            try {

                    while(listIter.hasNext()){

                    Map.Entry<Socket,String> clientrequest = listIter.next();
                    Socket cclient = clientrequest.getKey();
                    String crequest = clientrequest.getValue();

                    DataOutputStream tocclient = getOutputStream(cclient);

                        tocclient.writeUTF("Reset : Server Reseting closing connection.");
                        listIter.remove();
                        cclient.close();

                }

                DataOutputStream toclient = getOutputStream(client);    
                toclient.writeUTF("Reset : Server Reseting closing connection.");
                client.close();

            } catch (Exception e) {

                e.printStackTrace();
            }

        }

    }

    private void processRequest(String clientinput){

        boolean foundpair = false;
        //get the socket with matching request      
        Iterator<Map.Entry<Socket,String>> clientIter = SafeWalkServer.clientRequests.iterator();
        while(clientIter.hasNext()){            

            Map.Entry<Socket,String> clientrequest = clientIter.next();
            Socket cclient = clientrequest.getKey();
            String crequest = clientrequest.getValue();

            if(IsAPair(clientinput,crequest)){              

                try {

                    DataOutputStream tocclient = getOutputStream(cclient);
                    tocclient.writeUTF("Pair : " + clientinput);
                    //tocclient.close();

                    DataOutputStream toclient = getOutputStream(client);
                    toclient.writeUTF("Pair : " + crequest);
                    //toclient.close();

                    client.close();
                    cclient.close();

                    clientIter.remove();

                    foundpair = true;
                    break;

                } catch (Exception e) {

                    e.printStackTrace();
                }


            }           
        }

        if(!foundpair){

            DataOutputStream toclient = getOutputStream(client);
            try {
                toclient.writeUTF("Pending : waiting for pair.");
                //toclient.close();
            } catch (Exception e) {

                e.printStackTrace();
            }           

            Map.Entry<Socket, String> currententry = new AbstractMap.SimpleEntry<Socket, String>(client, clientinput);
            SafeWalkServer.clientRequests.add(currententry);
        }

    }


    private DataInputStream getInputStream(Socket lclient){

        DataInputStream inputstream = null;

        try {
            InputStream inFromClient  = lclient.getInputStream();
            inputstream = new DataInputStream(inFromClient);        
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }     

        return inputstream;
    }

    private DataOutputStream getOutputStream(Socket lclient){

        DataOutputStream outputstream = null;

        try {
            OutputStream intoClient  = lclient.getOutputStream();
            outputstream = new DataOutputStream(intoClient);        
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }     

        return outputstream;
    }

    private boolean IsAPair(String clientinput1,String clientinput2){

        String[] inputtokens = clientinput1.split(",");

        String from = inputtokens[1].trim();
        String to = inputtokens[2].trim();

        String[] inputtokens1 = clientinput2.split(",");

        String from1 = inputtokens1[1].trim();
        String to1 = inputtokens1[2].trim();

        if(from.equals(from1)){

            if(to.equals(to1) && to.equals("*"))        
                return false;       

            if(to.equals(to1) && !to.equals("*"))
                return true;

            if(!to.equals(to1) && (to.equals("*")||to1.equals("*")))
                return true;
        }

        return false;
    }

}

so this above code is totally my server code. And then my client code is:

public class SafeWalkClient extends JFrame implements ActionListener {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private JPanel contentPane;
    static public JTextField text;
    static public JTextArea textarea;

    private List<String> locations = new ArrayList<String>();   
    private List<String> commands = new ArrayList<String>();


    /**
     * Launch the application.
     */
    public static void main(String[] args) {        


        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    SafeWalkClient frame = new SafeWalkClient();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }


        });


    }

    /**
     * Create the frame.
     */
    public SafeWalkClient() {

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        JButton post = new JButton("Post");
        post.setBounds(322, 55, 89, 23);
        contentPane.add(post);
        post.addActionListener(this);

        textarea = new JTextArea();
        textarea.setBounds(26, 145, 275, 106);
        contentPane.add(textarea);

        JLabel lblRequest = new JLabel("REQUEST");
        lblRequest.setBounds(26, 31, 96, 14);
        contentPane.add(lblRequest);

        JLabel lblResponse = new JLabel("RESPONSE");
        lblResponse.setBounds(26, 119, 96, 14);
        contentPane.add(lblResponse);

        text = new JTextField();
        text.setBounds(26, 56, 275, 20);
        contentPane.add(text);
        text.setColumns(10);

        locations.add("CL50");
        locations.add("EE");
        locations.add("LWSN");
        locations.add("PMU");
        locations.add("PUSH");

        commands.add(":LIST_PENDING_REQUESTS");
        commands.add(":RESET");
        commands.add(":SHUTDOWN");



    }

    @Override
    public void actionPerformed(ActionEvent e) {


        if(!validateUserInput()){


            return;
        }

        try{

            //connect to the server and get the socket
            Socket serverconn = new Socket("127.0.0.1",80); 

            RequestHandler clientHandler = new RequestHandler(serverconn);
            clientHandler.start();

        }
        catch(Exception e1){
            e1.printStackTrace();
        }


    }

    private boolean validateUserInput(){

        String userinput = text.getText();          

        if(userinput.startsWith(":")){  //process for command

            if(commands.contains(userinput))
                return true;            
        }else{  //process for request

            String[] inputtokens = userinput.split(",");
            if(inputtokens.length!=4)
                return false;

            String from = inputtokens[1].trim();
            String to = inputtokens[2].trim();

            if(locations.contains(from) && (locations.contains(to)||to.equals("*")))
                return true;            
        }

        return false;
    }



}           


I am just writing a request to the server here and getting back the response.

here again i have a thread called RESPONSE HANDLER:

public class ResponseHandler extends Thread {

    private Socket client;
    private String hostname ;
    private int port;


    public ResponseHandler(String lhostname , int lport) throws UnknownHostException, IOException {
        hostname = lhostname;
        port = lport;
    }

    public void run(){

        /*Looper.prepare();
        Looper.loop();*/

        String userinput = SafeWalkClient.reqtext.getText().toString();

        try{

            client = new Socket(hostname , port);
            //prepare input / output streams
            OutputStream outToServer = client.getOutputStream();
            DataOutputStream toserver = new DataOutputStream(outToServer);

            InputStream inFromServer = client.getInputStream();
            DataInputStream fromserver = new DataInputStream(inFromServer);

            //start
            toserver.writeUTF(userinput);   //send the request/command to the server

            String serverrespose = fromserver.readUTF();  //get the response from server            

            if(onResponse(serverrespose)){              

                serverrespose = fromserver.readUTF();   //wait for pending respose

                if(!onResponse(serverrespose)){
                    fromserver.close();
                    toserver.close();
                    client.close();
                }

            }else{              
                fromserver.close();
                toserver.close();
                client.close();
            }

        }catch(Exception e){
            e.printStackTrace();

        }

    }

    private boolean onResponse(String output) { 

        Message msg = Message.obtain();
        msg.obj = output;
        SafeWalkClient._handler.sendMessage(msg);

        if(output.contains("List :") || output.contains("Shutdown :") || output.contains("Reset :")|| output.contains("Pair :")){                       
            return false;                       
        }
        else if(output.contains("Pending :")){  
            return true;
        }       

        return false;

    }

}

And this works without any error.But obvioulsy you will have to check the port for your IP that wether it;s open or not.Hope it helps..:)

P.S: Prefre using threads in your server and client communication as it will be more effective..!