user3344370
user3344370

Reputation:

Thread server/client stops after 2nd client joins

I have a server which uses multiple threads to accept multiple clients. I have it at the moment that when a client types something, it appears on the server as Client: text This works fine for 1 client. However the problem is when a second client joins.

They join fine and they can type fine. But the first client can only type 1 more thing then they stop, i.e their messages doesn't appear on the server. I presume they can do 1 as the method has been started but doesn't repeat. I've tried a while (true) loop (as seen in the code) and recalling the method at the end, neither work. I'm new to programming so don't have much expertise in this. Please find the code below :) (Note, indention is correct, just hasn't copied across properly)

Server:

    package dod;

    import java.net.*;
    import java.util.*;
    import java.util.concurrent.atomic.AtomicInteger;
    import java.io.*;

    public class Server implements Runnable
    {
    PrintWriter out;
    BufferedReader in;
    Socket clientSocket;
    ServerSocket serverSocket;
    int portNumber;
    AtomicInteger numClients = new AtomicInteger(0);


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

        s.startup();
    }

    public void run()
    {}


    /**
     * Start the server on the user picked port
     */
    public void startup()
    {   
        try 
        {
            System.out.println("Enter a port");
            Scanner dif = new Scanner(System.in);
            portNumber = Integer.parseInt(dif.nextLine());
            dif.close();

            serverSocket = new ServerSocket(portNumber);
            newThread();
        }
        catch (IOException e) {
            System.out.println("Error");
            System.exit(0);
        }
    }


    public void newThread()
    {
        Thread thread =new Thread("C"+numClients.getAndIncrement())
        {
            public void run()
            {
                accept();
            }
        };
        thread.start();
    }

    public void accept()
    {
        try
        {
            clientSocket = serverSocket.accept();
            System.out.println("A new client has just connected.");
        } catch(IOException e)
        {
            System.out.println("error");
            System.exit(0);
        }
        newThread();
        listenCommand();

    }


    public void listenCommand()
    {
        while (true)
        {
            try
            {
                out = new PrintWriter(clientSocket.getOutputStream(), true);                   
                in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

                String userInput;
                while ((userInput = in.readLine()) != null)
                {
                    System.out.println("client: " + userInput);
                }
            } catch (IOException e)
            {
                System.out.println("Error");
                System.exit(0);
            }
        }
    }
}

Client:

    package dod;

    import java.io.*;
    import java.net.*;


    public class Client
    {
    public static void main(String[] args) throws IOException {
        String hostName = args[0];
        int portNumber = Integer.parseInt(args[1]);

        try {
            Socket serverSocket = new Socket(hostName, portNumber);
            PrintWriter out = new PrintWriter(serverSocket.getOutputStream(), true);
            BufferedReader in = new BufferedReader(new InputStreamReader(serverSocket.getInputStream()));
            BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));

            String userInput;
            while ((userInput = stdIn.readLine()) != null)
            {
                out.println(userInput);
            }
        } catch(UnknownHostException e) {
            System.out.println("error in host");
        } catch(IOException e) {
            System.out.println("error in IO");
        }


    }
}

Thank you! :)

Upvotes: 1

Views: 197

Answers (1)

Raul Guiu
Raul Guiu

Reputation: 2404

*emphasized text*In the Server class you should have a Thread listening for new clients arriving and assigning them their own socket. You have the socket and the streams as a member variables, so everytime a new client comes you replace the socket. Also you open a new Thread for the accept connection, instead for the client itself.

Check the following (See that the client socket is another thread and I created a Runnable for it):

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.atomic.AtomicInteger;

public class Server
{
    ServerSocket serverSocket;
    int portNumber;
    AtomicInteger numClients = new AtomicInteger(0);


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

        s.startup();
    }


    /**
     * Start the server on the user picked port
     */
    public void startup()
    {   
        try 
        {
            System.out.println("Enter a port");
            Scanner dif = new Scanner(System.in);
            portNumber = Integer.parseInt(dif.nextLine());
            dif.close();

            serverSocket = new ServerSocket(portNumber);
            newThread();
        }
        catch (IOException e) {
            System.out.println("Error");
            System.exit(0);
        }
    }


    public void newThread()
    {
        Thread thread =new Thread("C"+numClients.getAndIncrement())
        {
            public void run()
            {   
                while(true) {
                    try {
                        accept();
                    } catch (Exception e) {
                        // lof the exception
                    }
                }
            }
        };
        thread.start();
    }

    public void accept()
    {
        try
        {
            Socket clientSocket = serverSocket.accept();
            new Thread(new ClientSocket(clientSocket)).start();
            System.out.println("A new client has just connected.");
        } catch(IOException e)
        {
            System.out.println("User disconnected");
            System.exit(0);
        }
    }


    class ClientSocket implements Runnable {
        Socket clientSocket;

        public ClientSocket(Socket clientSocket) {
            this.clientSocket = clientSocket;
        }

        public void run() {
            {
                try
                {
                    PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);                   
                    BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

                    String userInput;
                    while ((userInput = in.readLine()) != null)
                    {
                        System.out.println("client: " + userInput);
                    }
                } catch (IOException e)
                {
                    System.out.println("Error. Probably client disconnected");
                    // System.exit(0); do you want to exist when a client disconnects?
                }
            }
        }
    }
}

Upvotes: 1

Related Questions