Results 1 to 20 of 20
  1. #1
    Wnt2bsleepin is offline Senior Member
    Join Date
    Feb 2012
    Posts
    219
    Rep Power
    3

    Default Have server echo output to multiple clients

    I have been following the Java tutorials about networking, and I have modified the code to turn it into a chat server and client. The problem is that the server only echos back to the client that initiated the connection. The problem seems to be with the server having a new thread for ever connection to it. How do I get it to echo out the same thing to the clients?

    Server:
    Java Code:
    import java.net.*;
    import java.util.Scanner;
    import java.io.*;
    
    public class Server {
        public static void main(String[] args) throws IOException {
        	
        	Boolean accept = true; //Determines if the server is going to accept more connections.  
        	//int maxConnections = 20; 
            ServerSocket serverSocket = null;
            Scanner input = new Scanner(System.in);
            System.out.println("Enter the port number to listen on");  
            int port = input.nextInt(); 
            try
            {
             serverSocket = new ServerSocket(port);
             System.out.println("Listening on port: " + port); 
            } catch (Exception e) {System.err.println("Could not listen on port: "); System.exit(-1);}
            
            while(accept)
            {
            	new ServerThread(serverSocket.accept()).start();
            	//maxConnections++; 
            	 
            }
            
           serverSocket.close(); 
        
        }
        
        
       
            
    }
    Server Thread:
    Java Code:
    import java.net.*; 
    import java.io.*; 
    
    
    public class ServerThread extends Thread 
    {
    	
    	private  Socket socket = null;
    	private  int numPeople; 
    	private  PrintWriter out;
    	private  String name; 
    	private int id; 
    	BufferedReader in; 
    	
    	public ServerThread(Socket socket){
    		super("ServerThread");
    		this.socket = socket; 
    	}
    
    	
    	public void run()
    	{
    		try{
    			out = new PrintWriter(socket.getOutputStream(), true);
    			in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
    			String inputLine;
    			numPeople(true); 
    			String Name = in.readLine(); 
    			String SUID = in.readLine();
    			int UID = Integer.parseInt(SUID); 
    			Name(Name); 
    			UID(UID); 
    			while((inputLine = in.readLine()) != null)
    			{
    				
    				out.println("(UID: " + SUID + ") " + name + ": " + inputLine);
    				if(inputLine.equalsIgnoreCase("Quit")) {Disconnect();} 
    				if(inputLine.equalsIgnoreCase("list")) {out.println("Number of people in the server: " + numPeople);}  
    			}
    			
    			 
    			numPeople(false); 
    		}
    		
    		catch (IOException e)
    		{
    			e.printStackTrace(); 
    		}
    		
    		
    		
    	}
    	
    	
    	public void numPeople(Boolean add)
    	{
    		if(add)numPeople++; 
    		
    		else numPeople--; 
    	}
    	
    	
    	public void Disconnect() throws IOException
    	{
    		out.close();
    		in.close();
    		socket.close();
    	}
    	
    	
    	public void Name(String name)
    	{
    		this.name = name; 
    	}
    	
    	public void UID(int id)
    	{
    		this.id = id; 
    	}
    }
    Here is the client:

    Java Code:
    import java.io.*;
    import java.net.*; 
    import java.util.Scanner;
    
    public class EchoClient {
    	
    	  
    	
    	public static void main(String[] args) throws IOException
    	{
    		Socket echoSocket = null;
    		PrintWriter out = null; 
    		BufferedReader in = null;
    		String host = null; 
    		Scanner input = new Scanner(System.in);
    		System.out.println("Please choose: Press 1 for Local. Press 2 for Internet. Press 3 to connect to House");
    		int choice = input.nextInt();
    		if(choice == 1) { host = "localhost";} 
    		if(choice == 2) {System.out.println("Please enter the address of the server: ");  host = input.next();  } 
    		if(choice == 3) {host = "98.116.184.251"; } 
    		System.out.println("Connecting to: " + host);
    		
    		System.out.println("Enter the port to connect to: ");
    		
    		int port = input.nextInt(); 
    		
    		System.out.println("Please enter the name you would like to use for this chat: ");
    		
    		String name = input.next(); 
    		
    		int UID = ((int)Math.random() * 200) + name.hashCode() ;
    		String SUID = Integer.toString(UID); 
    		try{
    			echoSocket = new Socket(host, port);
    			out = new PrintWriter(echoSocket.getOutputStream(), true);
    			
    			in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream())); 
    			System.out.println("Connection Successful"); 
    			out.println(name); 
    			System.out.println("Your UID is: " + UID); 
    		}
    		
    		catch (UnknownHostException e)
    		{
    			System.err.println("Don't know the host: " + echoSocket.getInetAddress());
    			System.exit(1);
    		}
    		
    		catch (IOException e)
    		{
    			System.err.println("Couldn't get I/O for: " + host + ".\nPerhaps the Server is not running");
    			System.exit(1);
    		}
    		
    		BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); 
    		String userInput;
    		out.println(UID); 
    		while((userInput = stdIn.readLine()) != null) 
    		{
    			
    			out.println(userInput);
    			String InputLine = in.readLine(); 
    			System.out.println(InputLine); 
    		}
    		
    		out.close();
    		in.close();
    		stdIn.close();
    		echoSocket.close(); 
    	}
    
    }
    Any help is appreciated.
    Last edited by Wnt2bsleepin; 04-29-2012 at 12:38 AM.

  2. #2
    k1ng is offline Member
    Join Date
    Apr 2012
    Posts
    59
    Rep Power
    0

    Default Re: Have server echo output to multiple clients

    You need to keep reference to each client at this point

    Java Code:
    Socket client = serverSocket.accept();
    and keep it (in a structure with all your other clients) somewhere that can be accessed from the part that wants to echo to it then iterate over all your clients and send the echo to each.

    I wrote a basic chat client that did something like this a while back, it's here -> https://sourceforge.net/projects/roxcom/

  3. #3
    Wnt2bsleepin is offline Senior Member
    Join Date
    Feb 2012
    Posts
    219
    Rep Power
    3

    Default Re: Have server echo output to multiple clients

    Should I do something like

    Java Code:
    ServerThread a = new ServerThread(serverSocket.accept()).start();
    List.add(a);
    Create a new ServerThread and store it either in an array, or a linked list?

  4. #4
    k1ng is offline Member
    Join Date
    Apr 2012
    Posts
    59
    Rep Power
    0

    Default Re: Have server echo output to multiple clients

    No, you need a reference to the client to send information to it, the client is being hidden the way you are doing it, it's here

    Java Code:
    Socket client = serverSocket.accept();
    List.add(client);
    ServerThread a = new ServerThread(client).start();

  5. #5
    Wnt2bsleepin is offline Senior Member
    Join Date
    Feb 2012
    Posts
    219
    Rep Power
    3

    Default Re: Have server echo output to multiple clients

    Quote Originally Posted by k1ng View Post
    No, you need a reference to the client to send information to it, the client is being hidden the way you are doing it, it's here

    Java Code:
    Socket client = serverSocket.accept();
    List.add(client);
    ServerThread a = new ServerThread(client).start();
    I ended up doing that

    Java Code:
    Socket client = serverSocket.accept(); 
            	connected[index] = client;
            	index++; 
            	ServerThread a = new ServerThread(client); 
            	a.start();
    Storing the newly created Socket in an array. I could not do

    Java Code:
    ServerThread a = new ServerThread(client).start();
    as it was throwing an error. Now I just have to figure out how to get the server to send the information back to each client right?

  6. #6
    k1ng is offline Member
    Join Date
    Apr 2012
    Posts
    59
    Rep Power
    0

    Default Re: Have server echo output to multiple clients

    You don't need to figure it out, you already did it using 'echoSocket'. Get the output stream to the client and write to it.

    Your code...
    Java Code:
                echoSocket = new Socket(host, port);  
                out = new PrintWriter(echoSocket.getOutputStream(), true);
                 
                in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
                System.out.println("Connection Successful");
                out.println(name);

  7. #7
    Wnt2bsleepin is offline Senior Member
    Join Date
    Feb 2012
    Posts
    219
    Rep Power
    3

    Default Re: Have server echo output to multiple clients

    It's not sending out to all the clients. I have two connected, and they only echo back what is typed to them. Here are the changes I made.

    Java Code:
    import java.net.*;
    import java.util.Scanner;
    import java.io.*;
    
    public class Server {
        public static void main(String[] args) throws IOException {
        	
        	Socket[] connected = new Socket[100]; 
        	int index = 0; 
        	Boolean accept = true; //Determines if the server is going to accept more connections. Implement at a later time using a getter and a setter method. 
        	//int maxConnections = 20; 
            ServerSocket serverSocket = null;
            Scanner input = new Scanner(System.in);
            System.out.println("Enter the port number to listen on");  
            int port = input.nextInt(); 
            try
            {
             serverSocket = new ServerSocket(port);
             System.out.println("Listening on port: " + port); 
            } catch (Exception e) {System.err.println("Could not listen on port: " + port); System.exit(-1);}
            
            while(accept)
            {
            	Socket client = serverSocket.accept(); 
            	connected[index] = client;
            	index++; 
            	ServerThread a = new ServerThread(client);
            	a.start(); 
            }
            
           serverSocket.close(); 
        
        }
        
        
       
            
    }
    Nothing else changed.

  8. #8
    k1ng is offline Member
    Join Date
    Apr 2012
    Posts
    59
    Rep Power
    0

    Default Re: Have server echo output to multiple clients

    Each client has an in and an out, you need to watch (on the server end) for 'in' client messages then go through all the other clients and send the same message to their 'out'

  9. #9
    Wnt2bsleepin is offline Senior Member
    Join Date
    Feb 2012
    Posts
    219
    Rep Power
    3

    Default Re: Have server echo output to multiple clients

    Quote Originally Posted by k1ng View Post
    Each client has an in and an out, you need to watch (on the server end) for 'in' client messages then go through all the other clients and send the same message to their 'out'
    So that is something that I should do in my Server class, not my ServerThread class? Since my Server class is the one that has the array with all the connected clients.

  10. #10
    k1ng is offline Member
    Join Date
    Apr 2012
    Posts
    59
    Rep Power
    0

    Default Re: Have server echo output to multiple clients

    Yes but the problem you then face is that accept() will freeze your program and not allow the server to distribute the message sent from a client to the other clients. Perhaps a new thread you can move the accept() method into (either another Thread class or an embedded Runnable() ) so that the server is free to check for client messages and distribute them to other clients.

  11. #11
    Wnt2bsleepin is offline Senior Member
    Join Date
    Feb 2012
    Posts
    219
    Rep Power
    3

    Default Re: Have server echo output to multiple clients

    Isn't accept needed on the Socket for it to accept the connection? If I were to put accept() into another thread, how would I get it to apply to the newly created Socket?

  12. #12
    k1ng is offline Member
    Join Date
    Apr 2012
    Posts
    59
    Rep Power
    0

    Default Re: Have server echo output to multiple clients

    Accept is required but what it does is halt the execution of the program and waits for a connection. Usually it's not good practice to put anything in the main thread of execution that freezes the program in case a. nothing ever connects, b. something goes wrong. Two way of doing it would be

    1. add a synchronized (synchronized so that threads accessing it at the same time dont mess things up) method to add to the list of clients that the accept thread uses
    2. create custom event listeners for messages being sent

  13. #13
    Wnt2bsleepin is offline Senior Member
    Join Date
    Feb 2012
    Posts
    219
    Rep Power
    3

    Default Re: Have server echo output to multiple clients

    OK, so I went with the synchronized method to add the clients to the list.

    Java Code:
      public synchronized static void addClient(Socket client)
        {
        	connected[index] = client; 
        	index++; 
        }
    and here is what the call looks like

    Java Code:
     while(accept)
            {
            	Socket client = serverSocket.accept();  
            	addClient(client);  
            	ServerThread a = new ServerThread(client);
            	a.start(); 
            }
    Now all I have to do is get it to output the stream to all the clients?

  14. #14
    k1ng is offline Member
    Join Date
    Apr 2012
    Posts
    59
    Rep Power
    0

    Default Re: Have server echo output to multiple clients

    That'll work, now move your accept method into a runnable so it can run away and accept connections then deal with incoming and outgoing messages in your main loop/thread :)

  15. #15
    Wnt2bsleepin is offline Senior Member
    Join Date
    Feb 2012
    Posts
    219
    Rep Power
    3

    Default Re: Have server echo output to multiple clients

    So close. What do you mean by a runnable? Should I be moving this part
    Java Code:
    Socket client = serverSocket.accept();
    into its own synchronized method, so it can be called when needed? Then I leave the rest of the code where it is?

  16. #16
    k1ng is offline Member
    Join Date
    Apr 2012
    Posts
    59
    Rep Power
    0

    Default Re: Have server echo output to multiple clients

    Should probably throw

    Java Code:
               Socket client = serverSocket.accept(); 
               addClient(client); 
               ServerThread a = new ServerThread(client);
               a.start();
    into it's own thread, it's only accept that needs to be there but the others use 'client' which returns from accept. Runnable is an interface that says something can be run, a Thread basically as Thread implements Runnable.

  17. #17
    Wnt2bsleepin is offline Senior Member
    Join Date
    Feb 2012
    Posts
    219
    Rep Power
    3

    Default Re: Have server echo output to multiple clients

    Ok, I modified the code as posted

    Java Code:
    import java.net.*;
    import java.util.Scanner;
    import java.io.*;
    
    public class Server {
    	
    	private static int index = 0; 
    	
    	private static Socket[] connected = new Socket[100];
    	
    	private static ServerSocket serverSocket; 
    	
    	
        public static void main(String[] args) throws IOException {
        	
        	 
        	 
        	Boolean accept = true; //Determines if the server is going to accept more connections. Implement at a later time using a getter and a setter method. 
        	//int maxConnections = 20; 
            
            Scanner input = new Scanner(System.in);
            System.out.println("Enter the port number to listen on");  
            int port = input.nextInt(); 
            try
            {
             serverSocket = new ServerSocket(port);
             System.out.println("Listening on port: " + port); 
            } catch (Exception e) {System.err.println("Could not listen on port: " + port); System.exit(-1);}
            
            while(accept)
            {
            	Connect(); 
            }
            
            serverSocket.close(); 
        
        }
        
        
        public synchronized static void addClient(Socket client)
        {
        	connected[index] = client; 
        	index++; 
        }
    
        
        public synchronized static void Connect() throws IOException
        {
        	Socket client = serverSocket.accept();
        	addClient(client);  
        	ServerThread a = new ServerThread(client);
        	a.start();
        }
        
      
        
        
       
            
    }
    Now anytime someone tries to connect to the server, it will make a call to those methods and then add them to the array of Sockets. I now have to get the output streams to those clients stored in the array, and send the data down the pipe right?

  18. #18
    k1ng is offline Member
    Join Date
    Apr 2012
    Posts
    59
    Rep Power
    0

    Default Re: Have server echo output to multiple clients

    Check all the output streams of all the clients then when one has something to say, post it to the input stream of all the others :)

    This isn't the best way to do all this of course but it is the simplest.

  19. #19
    Wnt2bsleepin is offline Senior Member
    Join Date
    Feb 2012
    Posts
    219
    Rep Power
    3

    Default Re: Have server echo output to multiple clients

    I got it to send the input from one client to another, but it won't update the screen on the client unless I hit enter or something.
    I added the following changes to the code, everything else remains the same.

    Java Code:
    import java.net.*;
    import java.util.Scanner;
    import java.io.*;
    
    public class Server {
    	
    	private static int index = 0; 
    	
    	public static Socket[] connected = new Socket[100];
    	
    	private static ServerSocket serverSocket; 
    	
    	private static PrintWriter out,sout;
    	
    	private static int numConnected = 0; 
    	
        public static void main(String[] args) throws IOException {
        	
        	 
        	 
        	Boolean accept = true; //Determines if the server is going to accept more connections. Implement at a later time using a getter and a setter method. 
        	//int maxConnections = 20; 
            
            Scanner input = new Scanner(System.in);
            System.out.println("Enter the port number to listen on");  
            int port = input.nextInt(); 
            try
            {
             serverSocket = new ServerSocket(port);
             System.out.println("Listening on port: " + port); 
            } catch (Exception e) {System.err.println("Could not listen on port: " + port); System.exit(-1);}
            
            while(accept)
            {
            	Connect(); 
            }
            
            serverSocket.close(); 
        
        }
        
        
        public synchronized static void addClient(Socket client)
        {
        	connected[index] = client; 
        	index++; 
        	numConnected++; 
        }
    
        
        public synchronized static void Connect() throws IOException
        {
        	Socket client = serverSocket.accept();
        	
        	addClient(client);  
        	ServerThread a = new ServerThread(client);
        	a.start();
        }
        
        
        /**Takes the input from the client, including message and socket. It then goes through the array of currently
         * connected sockets and outputs the message string to them. It then sends a message sent string to 
         * the client that originated the message. 
         */
        public static void writeMessage(String message, Socket source) throws IOException
        {
        	for(int i = 0; i < numConnected; i++)
        	{
        		Socket output = connected[i]; 
        		sout = new PrintWriter(source.getOutputStream(), true); 
        		out = new PrintWriter(output.getOutputStream(),true); 
        		sout.println("Message Sent"); 
        		out.println(message); 
        	}
        	
        }
        
      
        
        
       
            
    }
    the method writeMessage() is new.

    here is a minor change to the ServerThread class.
    Java Code:
    import java.net.*; 
    import java.io.*; 
    
    
    public class ServerThread extends Thread 
    {
    	
    	private  Socket socket = null;
    	private  int numPeople; 
    	private  PrintWriter out;
    	private  String name; 
    	private int id; 
    	BufferedReader in; 
    	
    	public ServerThread(Socket socket){
    		super("ServerThread");
    		this.socket = socket; 
    		
    	}
    
    	
    	public void run()
    	{
    		try{
    			out = new PrintWriter(socket.getOutputStream(), true);
    			in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
    			String inputLine;
    			String Name = in.readLine(); 
    			String SUID = in.readLine();
    			int UID = Integer.parseInt(SUID); 
    			Name(Name); 
    			UID(UID); 
    			while((inputLine = in.readLine()) != null)
    			{
    				
    				//out.println("(UID: " + SUID + ") " + name + ": " + inputLine);
    				Server.writeMessage("(UID: " + SUID + ") " + name + ": " + inputLine, socket); 
    				if(inputLine.equalsIgnoreCase("Quit")) {Disconnect();} 
    				if(inputLine.equalsIgnoreCase("list")) {out.println("Number of people in the server: " + numPeople);}  
    			}
    			
    			 
    			 
    		}
    		
    		catch (IOException e)
    		{
    			e.printStackTrace(); 
    		}
    		
    		
    		
    	}
    	
    	
    	
    	
    	
    	public void Disconnect() throws IOException
    	{
    		out.close();
    		in.close();
    		socket.close();
    	}
    	
    	
    	public void Name(String name)
    	{
    		this.name = name; 
    	}
    	
    	public void UID(int id)
    	{
    		this.id = id; 
    	}
    }
    I just added a call for the writeMessage method.

    How do I get it to output the messages without the me having to hit enter.

  20. #20
    Wnt2bsleepin is offline Senior Member
    Join Date
    Feb 2012
    Posts
    219
    Rep Power
    3

    Default Re: Have server echo output to multiple clients

    I think it may have something to do with the client. Does the client need to constantly check to see if there is an incoming message? Would a while loop fix that? Or is this problem server side?

Similar Threads

  1. multiple clients single server via sockets
    By acks in forum Networking
    Replies: 3
    Last Post: 04-12-2011, 08:44 AM
  2. how to connect a server to multiple clients
    By yontan8888 in forum Networking
    Replies: 1
    Last Post: 02-02-2011, 12:42 PM
  3. Replies: 1
    Last Post: 10-26-2010, 12:21 AM
  4. how to connect a server to multiple clients?
    By azhar in forum Networking
    Replies: 15
    Last Post: 03-22-2010, 01:54 PM
  5. An echo server using UDP sockets
    By Java Tip in forum java.net
    Replies: 0
    Last Post: 04-07-2008, 09:09 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •