Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 16 of 16

Thread: Client and server socket conection - how to send IDs to clients

  1. #1
    Junior Member
    Join Date
    May 2014
    Posts
    8
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Client and server socket conection - how to send IDs to clients

    I have a server connected to two clients, and I want to send messages from one to another with only one client active at a time, so after every message send it waits for response from the other client. Therefore client should know if the first thing it needs to do is write a message to 2nd client or wait for a message from 1st one.


    This is the server side of my project:

        public void connect() throws IOException {
    		log(TA, "ServerSocket created. \nListering for connections...\n");
    		server = new ServerSocket(port, 2);
     
    		conn1 = server.accept();
    		output1 = new PrintWriter(conn1.getOutputStream());
    		input1 = new BufferedReader(new InputStreamReader(
    				conn1.getInputStream()));
    		log(TA, "User " + 1 + " connected.\n");
    		output1.println("1");
     
    		conn2 = server.accept();
    		output2 = new PrintWriter(conn2.getOutputStream());
    		input2 = new BufferedReader(new InputStreamReader(
    				conn2.getInputStream()));
    		log(TA, "User " + 2 + " connected.\n");
    		output2.println("2");
    		while (true) {
    			String text = input1.readLine();
     
    				TA.append("Player 1: " + text + "\n");
    				output2.println("Player 1: " + text);
     
    			text = input2.readLine();
     
    				TA.append("Player 2: " + text + "\n");
    				output1.println("Player 2: " + text);
    		}
     
    	}

    And this is the client:

        private static void connect() throws IOException {
    		conn = new Socket("192.168.0.25", port);
    		TA.append("Socket created.\n");
    		out = new PrintWriter(conn.getOutputStream(), true);
    		in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    		TA.append("Streams created.\n");
    		String inputLine;
    		while ((inputLine = in.readLine()) != null)
    		player_number = Integer.parseInt(inputLine);
    		TA.append("Your ID is " + player_number + " .");
    	}
     
    	public void actionPerformed(ActionEvent evt) {
    		String text = TF.getText();
    		TA.append("Me: " + text + "\n");
    		TF.selectAll();
    		TA.setCaretPosition(TA.getDocument().getLength());
    		if (player_number == 2)
    			try {
    				TA.append("Player 1: " + in.readLine());
    			} catch (IOException e1) {
    				e1.printStackTrace();
    			}
    		out.println(text);
    		if (player_number == 1)
    			try {
    				TA.append("Player 2: " + in.readLine());
    			} catch (IOException e1) {
    				e1.printStackTrace();
    			}
     
    	}

    What it should do is as soon as connection to one client is made, server should let it know if its 1st or 2nd one, and client should "aknowledge" it by writing `"Your ID is " + player_number + " ."`. This should happen before I enter anything to either textfields. But what happens now, I start the server and both clients, only get to `"Streams created"` message on clients and when I send something from 1st client it shows in server's textarea, but not in the other client. The client I send the message from just freezes.

    This is somehow related to the `parseInt` part because that's where the program stops, but i don't know why.


  2. #2
    Junior Member
    Join Date
    May 2014
    Posts
    3
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Client and server socket conection - how to send IDs to clients

    Post here: Java Networking

  3. #3
    Junior Member
    Join Date
    May 2014
    Posts
    8
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Client and server socket conection - how to send IDs to clients

    it looks like the code player_number = Integer.parseInt(inputLine); is called too soon and the server doesn't send the ID by the time, and that's why it freezes i guess. I put output1.println("1"); in a while(true) loop and it worked
    Last edited by Asalas77; May 8th, 2014 at 03:19 PM. Reason: double post

  4. #4
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    25,139
    Thanks
    65
    Thanked 2,720 Times in 2,670 Posts

    Default Re: Client and server socket conection - how to send IDs to clients

    Can you make a small, complete program that compiles, executes and shows the problem?
    If you don't understand my answer, don't ignore it, ask a question.

  5. #5
    Junior Member
    Join Date
    May 2014
    Posts
    8
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Client and server socket conection - how to send IDs to clients

    How small? Because there's pretty much nothing left except imports, definitions and constructors plus the code I already posted.

    Client:
     import java.awt.*;
    import java.awt.event.*;
    import java.io.*;
    import java.net.*;
    import java.util.*;
     
    import javax.swing.*;
     
    public class Client extends JFrame implements ActionListener{
            private static Socket conn;
            private static JTextArea TA;
            private static JTextField TF;
            private JPanel panel1;
            private final static int port = 1234;
            private ArrayList<Ship> myShips = new ArrayList();
            static PrintWriter out;
            static BufferedReader in;
            static int player_number = 1;
     
            public Client() {
                    super("Client");
                    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    setSize(new Dimension(400, 300));
                    Container c = getContentPane();
                    c.setBackground(Color.BLACK);
                    TA = new JTextArea();
                    TA.setEditable(false);
                    TA.setBackground(Color.BLACK);
                    TA.setForeground(Color.WHITE);
                    c.add(new JScrollPane(TA));
                    TF = new JTextField();
                    TF.setEditable(true);
                    TF.setBackground(Color.BLACK);
                    TF.setForeground(Color.WHITE);
                    c.add(TF, BorderLayout.SOUTH);
                    setVisible(true);
                    TF.addActionListener(this);
                    TA.append("Client started.\n");
            }
     
            public static void main(String[] args) {
     
                    new Client();
                    try {
                            connect();
     
                    } catch (IOException e) {
                            e.printStackTrace();
                    }// catch
     
            }
     
            private static void connect() throws IOException {
                    conn = new Socket("192.168.0.25", port);
                    TA.append("Socket created.\n");
                    out = new PrintWriter(conn.getOutputStream(), true);
                    in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                    TA.append("Streams created.\n");
                    String inputLine;
                    inputLine = in.readLine();
                    if(inputLine == null)
                            System.out.println("null");
                    player_number = Integer.parseInt(inputLine);
                    TA.append("Your ID is " + player_number + " .");
            }
     
            public void actionPerformed(ActionEvent evt) {
                    String text = TF.getText();
                    TA.append("Me: " + text + "\n");
                    TF.selectAll();
                    TA.setCaretPosition(TA.getDocument().getLength());
                    if (player_number == 2)
                            try {
                                    TA.append("Player 1: " + in.readLine());
                            } catch (IOException e1) {
                                    e1.printStackTrace();
                            }
                    out.println(text);
                    if (player_number == 1)
                            try {
                                    TA.append("Player 2: " + in.readLine());
                            } catch (IOException e1) {
                                    e1.printStackTrace();
                            }
     
            }
     
    }

    Server:
    import java.awt.*;
    import java.io.*;
    import java.net.*;
    import java.util.ArrayList;
     
    import javax.swing.*;
     
    public class Server extends JFrame {
            private ServerSocket server;
            private Socket conn1;
            private Socket conn2;
            private JTextArea TA;
            private JPanel panel1;
            private int port = 1234;
            PrintWriter output1;
            BufferedReader input1;
            PrintWriter output2;
            BufferedReader input2;
     
     
            public Server() {
                    super("Server");
                    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    setSize(new Dimension(400, 300));
                    Container c = getContentPane();
                    c.setBackground(Color.BLACK);
                    TA = new JTextArea();
                    TA.setEditable(true);
                    TA.setBackground(Color.BLACK);
                    TA.setForeground(Color.GREEN);
                    c.add(new JScrollPane(TA));
                    setVisible(true);
                    TA.append("Server started.\n");
            }
     
            public void start() {
                    try {
     
                            connect();
                    } catch (IOException ioe) {
                            System.out.println(ioe);
                    } catch (InterruptedException e) {
                            e.printStackTrace();
                    }
            }
     
            public void log(final JTextArea txt, final String message) {
                    SwingUtilities.invokeLater(new Runnable() {
                            public void run() {
                                    txt.append(message);
                            }
                    });
            }
     
            public void connect() throws IOException, InterruptedException {
                    log(TA, "ServerSocket created. \nListering for connections...\n");
                    server = new ServerSocket(port, 2);
     
                    conn1 = server.accept();
                    output1 = new PrintWriter(conn1.getOutputStream());
                    input1 = new BufferedReader(new InputStreamReader(
                                    conn1.getInputStream()));
                    log(TA, "User " + 1 + " connected.\n");
                    Thread.sleep(10000);
                            output1.println("1");
     
     
                    conn2 = server.accept();
                    output2 = new PrintWriter(conn2.getOutputStream());
                    input2 = new BufferedReader(new InputStreamReader(
                                    conn2.getInputStream()));
                    log(TA, "User " + 2 + " connected.\n");
                    output2.println("2");
                    while (true) {
                            String text = input1.readLine();
     
                            TA.append("Player 1: " + text + "\n");
                            output2.println("Player 1: " + text);
     
                            text = input2.readLine();
     
                            TA.append("Player 2: " + text + "\n");
                            output1.println("Player 2: " + text);
                    }
     
            }
    }

    and this to run the server:

    public class ServerLauncher {
     
    	public static void main(String[] args) {
    	    Server s = new Server();
    	    s.start();
    	}
     
    }


    See my edit above, the code to send ID to 1st client works when I put it in endless loop so i guess it's a synchronization issue between server sending the ID and client trying to read it.
    Last edited by Asalas77; May 8th, 2014 at 04:07 PM.

  6. #6
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    25,139
    Thanks
    65
    Thanked 2,720 Times in 2,670 Posts

    Default Re: Client and server socket conection - how to send IDs to clients

    Please post the code here, not as links to other sites.
    If you don't understand my answer, don't ignore it, ask a question.

  7. #7
    Junior Member
    Join Date
    May 2014
    Posts
    8
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Client and server socket conection - how to send IDs to clients

    Done that.

  8. #8
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    25,139
    Thanks
    65
    Thanked 2,720 Times in 2,670 Posts

    Default Re: Client and server socket conection - how to send IDs to clients

    There are missing class definitions.
    If you don't understand my answer, don't ignore it, ask a question.

  9. #9
    Junior Member
    Join Date
    May 2014
    Posts
    8
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Client and server socket conection - how to send IDs to clients

    Oh right, sorry about that. Those would be in the server:

            private ArrayList<Ship> player1Ships = new ArrayList();
            private ArrayList<Ship> player2Ships = new ArrayList();

    removed that code, it's not necessary, i just forgot about that part.



    This should be working now

  10. #10
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    25,139
    Thanks
    65
    Thanked 2,720 Times in 2,670 Posts

    Default Re: Client and server socket conection - how to send IDs to clients

    How are you debugging the code? I don't see anything printed on the console when the code executes.

    One possible problem I see is that there are several if statements that do NOT enclose the following code in {}s. That is dangerous and will create errors when the code is changed.
    If you don't understand my answer, don't ignore it, ask a question.

  11. #11
    Junior Member
    Join Date
    May 2014
    Posts
    8
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Client and server socket conection - how to send IDs to clients

    I was only printing to the JTextAreas and not console to check where the program stops. I changed the if statements but i dont think thats causing the problem.

    When is comes to writing and reading from a socket, should I initialize reading first and then send something to be read? or do i have to send the message first in order to be able to read it? because i think this is where the problem might be that i'm trying to read when nothing is send yet (or sending when nothing is reading yet)

  12. #12
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    25,139
    Thanks
    65
    Thanked 2,720 Times in 2,670 Posts

    Default Re: Client and server socket conection - how to send IDs to clients

    Try flushing the output after writing to it to push the data out of any buffers.

    I debug client server apps by running them in one jvm so all output goes to one console so the order of events is easy to see.
    Here is the code I use:
       public static void main(String[] args) {
          Thread t1 = new Thread(new Runnable() {
             public void run() {
       	    Server s = new Server();
    	       s.start();
             }
          });
          t1.start();
     
          try{Thread.sleep(100);}catch(Exception x){}
     
          Thread t2 = new Thread(new Runnable() {
             public void run() {
                try{Client.main(new String[]{"127.0.0.1", "8080"});}catch(Exception x){x.printStackTrace();}
             }
          });
          t2.start();
     
          Thread t3 = new Thread(new Runnable() {
             public void run() {
                try{Client.main(new String[]{"127.0.0.1", "8080"});}catch(Exception x){x.printStackTrace();}
             }
          });
          t3.start();
     
          // wait some and exit   in case app freezes
          try{Thread.sleep(30000);}catch(Exception x){}
          System.out.println("Exiting main");
          System.exit(0);
       }
    For this to work, all static variables need to be changed to be instance variables.
    If you don't understand my answer, don't ignore it, ask a question.

  13. #13
    Junior Member
    Join Date
    May 2014
    Posts
    8
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Client and server socket conection - how to send IDs to clients

    Thank you, the debug code really helped. I put system messages after every step in debugger, server and client and this is the output:

    Debugger: Starting server.
    Server: Constructor running.
    Server: GUI created.
    Server: setting up connections.
    Server: serversocket created.
    Debugger: Starting client 1..
    Client: Constructor running.
    Client: connecting to server.
    Server: connection 1 accepted.
    Client: Socket created.
    Server: output1 opened.
    Client: output stream opened.
    Server: input1 opened.
    Server: ID 1 sent.
    Client: input stream opened.
    Client: Waiting for ID.
    Debugger: Starting client 2..
    Client: Constructor running.
    Client: connecting to server.
    Server: connection 2 accepted.
    Client: Socket created.
    Server: output2 opened.
    Client: output stream opened.
    Server: input2 opened.
    Server: ID 2 sent.
    Server: conversation started.
    Client: input stream opened.
    Client: Waiting for ID.
    Exiting main

    I have a feeling that clients should start listening for IDs before server sends them, right? How can I change it or delay ID sending on server side?


    edit:

    to further test this, I ran server side ID sending in a loop

    int i = 1;
    while(true)
    {
    output1.println("1");
    if(i ==0)
         break;
    if(i%1000==0)
         System.out.println(i + " Server: ID 1 sent.");
    i++;
    }

    And from the output on console i see that server sends ID between 5000 and 6000 times before client accepts it.

    ...
    Client: Waiting for ID.
    1000 Server: ID 1 sent.
    2000 Server: ID 1 sent.
    3000 Server: ID 1 sent.
    4000 Server: ID 1 sent.
    5000 Server: ID 1 sent.
    Client: Received ID 1 .              <--
    6000 Server: ID 1 sent.
    ...
    73000 Server: ID 1 sent.
    Debugger: Starting client 2..
    Client: Constructor running.
    Client: connecting to server.
    Client: Socket created.
    Client: output stream opened.
    Client: input stream opened.
    Client: Waiting for ID.
    Exiting main

    I tried to do the same for the 2nd ID but it doesn't work, the client doesnt respond with "Received ID 2"
    Last edited by Asalas77; May 9th, 2014 at 08:46 AM.

  14. #14
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    25,139
    Thanks
    65
    Thanked 2,720 Times in 2,670 Posts

    Default Re: Client and server socket conection - how to send IDs to clients

    Another problem is doing potentially long running code from a listener. The listener runs on the EDT which is where the JVM executes to update the GUI. The long running code should be done on its own thread.
    If you don't understand my answer, don't ignore it, ask a question.

  15. #15
    Junior Member
    Join Date
    May 2014
    Posts
    8
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Client and server socket conection - how to send IDs to clients

    I still dont understand what I need to do. Which code is "potentially long running"? How do i make separate threads for the clients or the code?

  16. #16
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    25,139
    Thanks
    65
    Thanked 2,720 Times in 2,670 Posts

    Default Re: Client and server socket conection - how to send IDs to clients

    There is an example of how to use threads in post#12. It starts 3 threads to run the server and clients.
    Put the code that does the reading inside a thread
    If you don't understand my answer, don't ignore it, ask a question.

Similar Threads

  1. Java Socket:How i can set value jtext Field when Client Send Message
    By ning2014 in forum What's Wrong With My Code?
    Replies: 1
    Last Post: April 26th, 2014, 05:03 AM
  2. Muliple Client Server chat application..how to send message from server..
    By jesroni in forum What's Wrong With My Code?
    Replies: 3
    Last Post: September 14th, 2013, 11:17 PM
  3. Replies: 0
    Last Post: May 31st, 2012, 05:35 PM
  4. Multiple clients and one server. How to send data from one client to the others
    By u-will-neva-no in forum Java Theory & Questions
    Replies: 1
    Last Post: March 21st, 2012, 07:29 PM
  5. [SOLVED] Server Client does not send file
    By Kakashi in forum What's Wrong With My Code?
    Replies: 0
    Last Post: March 10th, 2011, 12:38 PM

Tags for this Thread