Search code examples
javasocketsdatainputstream

Java socket automated communication


I have a problem with the communication between a server and a client. I am trying to figure out a way of the communicating automatically because they have to exchange some parameters. However, with the code I wrote the server either keeps on sending the same message to the client after the client confirms the message or the client receives nothing at all. The sockets and everything have been setup up before. The function sendString() and receiveString() are identical inboth code examples. Is there a proper way of doing this? I dont get why this doesnt work...

Server:

String buffer;
    while(true){
        buffer = client.receiveString();
        if(buffer != null && buffer.equals("ready")){
            System.out.println("Client is ready");
            client.sendString("ready");
            while(true){
                buffer = client.receiveString();
                if(buffer != null && buffer.equals("k")){
                    System.out.println("stopped");
                    break;
                }
            }
            break;
        }
    }

public String receiveString() throws IOException{         //From the client class
    if(dataIn.available() > 0){
        int length = dataIn.readInt();
        byte[] b = new byte[length];
        dataIn.readFully(b, 0, b.length);

        return new String(b, Charset.forName("UTF-8"));
    }
    return null;
}

public void sendString(String msg) throws IOException{
    byte[] b = msg.getBytes(Charset.forName("UTF-8"));

    dataOut.writeInt(b.length);
    dataOut.write(b);
}

Client:

String buffer;
while(true){
    sendString("ready");
    buffer = receiveString();
    if(buffer!=null)
        System.out.println(buffer);
    if(buffer != null && buffer.equals("ready")){   
        System.out.println("Server is ready");
        sendString("k");
        break;
    }
}

Solution

  • This code might work in your case:

    Client.java

    public class Client {
        public static void main(String[] args) throws Exception {
            try (Socket socket = new Socket("localhost", 8080)) {
                try (BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());
                     Scanner in = new Scanner(socket.getInputStream())) {
                    System.out.println("Client: sending ready.");
                    writeLine("ready", out);
                    System.out.println("Client: sent ready.");
    
                    String line = in.nextLine();
                    if ("ready".equals(line)) {
                        System.out.println("Client: server is ready");
                        writeLine("k", out);
                    }
                }
            }
        }
    
        private static void writeLine(final String line, final BufferedOutputStream out) throws IOException {
            out.write((line +"\n").getBytes());
            out.flush();
        }
    }
    

    Server.java:

    public class Server {
    
        public static void main(String[] args) throws Exception {
            boolean running = true;
            try (ServerSocket socket = new ServerSocket(8080, 0)) {
                while (running) {
                    System.out.println("Waiting for client accept.");
                    try (final Socket client = socket.accept();
                         final Scanner in = new Scanner(client.getInputStream());
                         final BufferedOutputStream out = new BufferedOutputStream(client.getOutputStream())) {
                        System.out.println("Waiting for client ready.");
                        String line = readLine(in);
    
                        if ("ready".equals(line)) {
                            writeLine("ready", out);
    
                            while (running) {
                                line = readLine(in);
                                if (line != null && line.equals("k")) {
                                    System.out.println("Server: received stop signal");
                                    running = false;
                                } else {
                                    Thread.sleep(100);
                                    System.out.println("Server: waiting for command.");
                                }
                            }
                        }
                    }
                }
            }
        }
    
        private static String readLine(final Scanner in) {
            String line = in.nextLine();
            System.out.println("Server: client sent " + line);
    
            return line;
        }
    
        private static void writeLine(final String line, final BufferedOutputStream out) throws IOException {
            out.write((line + "\n").getBytes());
            out.flush();
        }
    }
    

    So what is happening here? Server socket waits for a client. If client connects, it waits for it to send something (in a blocking manner!). If its "ready", it checks for other commands.

    Note: This only works for a single server<->client connection at a time. Dunno if this suites your application. The Server gets shutdown if client sends "k", like in your case.