Home > Enterprise >  I'm misunderstanding something on how to set up sockets, but I'm not suer if it's cli
I'm misunderstanding something on how to set up sockets, but I'm not suer if it's cli

Time:02-03

I'm setting up a simple program to test starting a server, and I'm getting a silent failure state. My client seems to think it has sent, while my server doesn't think it's recieving. The two are managing the initial connection, it's just sending things after that where it's failing.

I've cut things down to the core of where it's currently failing I think.

Here's part of the Client code

public void Client (int port, String ip)
    {
        try {
            sock = new Socket(ip, port);
            System.out.println("Found the server.");
            streamInput = new DataInputStream(sock.getInputStream());

            // sends output to the socket
            streamOutput = new DataOutputStream(
                    sock.getOutputStream());
            streamOutput.writeChars("Client Begining Conversation");
            System.out.println(streamInput.readUTF());
        }
        catch (UnknownHostException u) {
            System.out.println(u);
            return;
        }
        catch (IOException i) {
            System.out.println(i);
            return;
        }
    }

    public static void main(String[] args) throws IOException {
        // create the frame

        try {

            ClientGui main = new ClientGui();
            main.Client(8000,"127.0.0.1");
            main.show(true);

        } catch (Exception e) {e.printStackTrace();}

Here's server code.

public Server(int port) throws Exception
    {
        ServerSocket gameServer = new ServerSocket(port);
        Socket gameSocket = gameServer.accept();
        System.out.println("Client has connected");

        // to send data to the client
        PrintStream dataOutput
                = new PrintStream(gameSocket.getOutputStream());

        // to read data coming from the client
        BufferedReader reader = new BufferedReader( new InputStreamReader(
                gameSocket.getInputStream()
                ));

        //play logic
        Play(reader,dataOutput);
public void Play(BufferedReader reader, PrintStream dataOutput) throws Exception
    {
        String received, textSent;
        System.out.println("Waiting for response.");
        received = reader.readLine();
        System.out.println("Client has responded");
        //contenue until 'Exit' is sent
        while (received != "Exit" || received != "exit") {
            System.out.println(received);
            textSent = received   "recieved";

            // send to client
            dataOutput.println(textSent);
        }
    }

My client gets to here -

Found the server.

and my server gets to here -

Trying to start server.
Client has connected
Waiting for response.

At which point, it just hangs forever, each side waiting for the other. It doesn't throw an error, it just... waits until I force it closed.

So it appears that I'm either doing something wrong when I send with "streamOutput.writeChars" in my client, or I'm doing something wrong when I receive with my server with "reader.readLine();", but I can't figure out what.

Or I could be doing something more fundamentally wrong.

CodePudding user response:

The problem is that reader.readLine() doesn’t return until it sees a new line character, but streamOutput.writeChars("Client Begining Conversation") doesn’t send one.

More generally, mixing a DataOutputStream on the client with a BufferedReader on the server won’t work reliably, as the latter expects plain text, while the former produces formatted binary data. For example, the character encoding might not match. The same applies to communication in the opposite direction with PrintStream and DataInputStream. It’s best to pick either a text based or binary protocol and then be consistent about the pair of classes used on both the client and server.

In the case of a text protocol, an explicit character encoding should be defined, as the default can vary between platforms. As a learning exercise, it might not matter, but it’s a good practice to be explicit about specifying a character encoding whenever handling networked communication. UTF-8 is a good choice unless there’s a specific reason to use another one.

In addition, it is generally preferred to use PrintWriter instead of PrintStream for text output in new code. Read this answer for an explanation.

  • Related