0

I need to make a TCP Server which accepts sockets from clients and receives data from them and send received data to all clients. to do that my Server class saves accepted connections to an ArrayList<Socket> and while wants to send data to clients:

Arraylist<Socket> sockets=Server.getSockets();
for(Socket current: sockets)
{
   ObjectOutputStream out=new ObjectOutputStream (current.getOutputStream());
   out.flush();
   out.writeObject(object);
   out.flush();
   out.close();
 }

but it doesn't work. what's wrong?

9
  • @KevinDTimm it's the name of the class in which a ServerSocket accepts sockets and saves them Commented Feb 1, 2013 at 13:37
  • Name of the class, but not an instance, so it's static? Commented Feb 1, 2013 at 14:27
  • @KevinDTimm yes, you are true Commented Feb 1, 2013 at 15:32
  • 1
    Simplest suggestion is to get this to work for one connection first, then expand it to multiple connections. Your project scope is rather large and trying to do all of it at once is a mistake. Going forward, I'd also (maybe) recommend spawning a thread for every connection and sending a message to each thread when you want to communicate with all your clients. Commented Feb 1, 2013 at 17:11
  • 1
    Don't create new object streams every time you need them. You must use the same object streams for the life of try socket, at both ends. Otherwise they don't work. Commented Feb 1, 2013 at 19:49

1 Answer 1

1

There is nothing wrong with your code snippet, the only problem which I can feel is that how your client code is implemented. Let us say your client code is something like this.

Socket clientSocket = new Socket(ip, port);
BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
while ( true ){
String sentence = inFromUser.readLine();
outToServer.writeBytes(sentence + '\n');
outToServer.flush();

DataInputStream is = new DataInputStream(clientSocket.getInputStream());
System.out.println(is.readLine());
}

Now this client is reading input from console and sending it to server, post that it blocks to wait for response. Lets assume server will send data to all[Which is what you want] if he receive a message 'fire'. Now there are two clients connected to server, ClientA and ClientB.

1. ClientA blocked at user-input (console)
2. User enter 'abc'
3. ClientA moves on sends 'abc' to server
4. ClientA blocks to read data from server
5. Server sends back 'abc' to ClientA [Assuming its an echo server]
6. ClientA reads the data, print it
7. ClientA moves back(while loop), blocked again for user input.

Same thing happen for ClientB, so now both are blocked for user input from console.
Lets say now ClientA user send our magic word ['fire' in this case], server identifies that its a magic word and start sending data to ClientA and ClientB,

Now here the important thing to notice, which is the state of ClientA and ClientB, at this point ClientA has just send the data and is at point 4, hence is blocked to read data from server, so when server sends the message it can read and display, whereas clientB is at point 1, blocked for getting data from console.. so even though server has send data ClientB has data to read, but it can't since its stuck at point 1, also you are closing the connection from server after write, so if ClientB somehow after sometime moves from point 1 to point 4, socket is already closed, hence again it will not be able to read. Though server has send data to both ClientA and ClientB, only ClientA is able to get it.

Phew!! Quite a long explanation, I guess it gives you some direction to solve your problem

Server code for reference

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;


public class BroadCastTCPServer {

    private static ArrayList<Socket> sockets = new ArrayList<Socket>();
    //Usage: java TCPServer port
    public static void main(String args[]){

        BroadCastTCPServer server = new BroadCastTCPServer();
        try {
            server.startServer("9999");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void startServer(String portStr) throws IOException {

        int port = Integer.parseInt(portStr);
        ServerSocket  serverSocket = new ServerSocket(port);

         System.out.println("Listening on IP:" +  serverSocket.getInetAddress().getHostAddress() + " Port:"+port);

         while(true){
            Socket connectionSocket = serverSocket.accept();
            sockets.add(connectionSocket);
            System.out.println("New client connection:" + connectionSocket.getRemoteSocketAddress());
            ClientHandler cl = new ClientHandler(connectionSocket);
            Thread clientThread = new Thread(cl);
            clientThread.start();
         }

    }

    public void sendAll() throws Exception{
        System.out.println("No of connections:" + sockets.size());
        for(Socket current: sockets){
            System.out.println(current.getRemoteSocketAddress());
           ObjectOutputStream out=new ObjectOutputStream (current.getOutputStream());
           out.flush();
           out.writeObject("Tata\n");
           out.flush();
           //out.close();
         }
    }

    class ClientHandler implements Runnable{

        Socket socket;
        public ClientHandler(Socket socket){
            this.socket = socket;
        }
        @Override
        public void run() {
            BufferedReader inFromClient = null;
            ObjectOutputStream out = null;
            BufferedWriter br = null;
            try {
                inFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                out=new ObjectOutputStream (socket.getOutputStream());
                OutputStreamWriter or= new OutputStreamWriter(out);
                br = new BufferedWriter(or);
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            while(true){
            String clientSentence= null;
            try {
                clientSentence = inFromClient.readLine() ;
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            System.out.println("Received: " + clientSentence);
            if (clientSentence.equalsIgnoreCase("fire")) {
                try {
                    sendAll();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }else{
                try {
                    br.write(clientSentence + "\n" );
                    br.flush();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            }
        }

    }

}
Sign up to request clarification or add additional context in comments.

3 Comments

thank you for your detailed explanation but unfortunately! my client and server are really more complicated and so hard to debug, you explained basis of TCP networking. by the way the code which I've written above is wrong as creates new streams each time, I changed that but now I have another problem, one of my clients can send data, the other one which is on the machine, on which the server is, too can send only once...
I can be of more help if you give your client code. I feel the error is in both side, server as well as client. I have pasted server code also for your reference.
I have written my code in a new question, please come and help me here: stackoverflow.com/questions/14665445/… thanx

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.