简体   繁体   中英

Best practice for reading / writing to a java server socket

How do you design a read and write loop which operates on a single socket (which supports parallel read and write operations)? Do I have to use multiple threads? Is my (java) solution any good? What about that sleep command? How do you use that within such a loop?

I'm trying to use 2 Threads:

Read

public void run() {
    InputStream           clientInput;
    ByteArrayOutputStream byteBuffer;
    BufferedInputStream   bufferedInputStream;
    byte[]                data;
    String                dataString;
    int                   lastByte;

    try {
        clientInput         = clientSocket.getInputStream();
        byteBuffer          = new ByteArrayOutputStream();
        bufferedInputStream = new BufferedInputStream(clientInput);

        while(isRunning) {  

            while ((lastByte = bufferedInputStream.read()) > 0) {
                byteBuffer.write(lastByte);
            }
                data       = byteBuffer.toByteArray();  
                dataString = new String(data);
                byteBuffer.reset();     
        }   

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

Write

public void run() {
    OutputStream clientOutput;
    byte[]       data;
    String       dataString;

    try {
        clientOutput = clientSocket.getOutputStream();

        while(isOpen) { 

            if(!commandQueue.isEmpty()) {
                dataString = commandQueue.poll();
                data       = dataString.getBytes();
                clientOutput.write(data);
            }                   
            Thread.sleep(1000);
        }       
        clientOutput.close();           
    } 
    catch (IOException e) {
        e.printStackTrace();
    } 
    catch (InterruptedException e) {
        e.printStackTrace();
    }
}

Read fails to deliver a proper result, since there is no -1 sent. How do I solve this issue?

Is this sleep / write loop a good solution?

There are basically three ways to do network I/O:

  1. Blocking. In this mode reads and writes will block until they can be fulfilled, so if you want to do both simultaneously you need separate threads for each.

  2. Non-blocking. In this mode reads and writes will return zero (Java) or in some languages (C) a status indication (return == -1, errno=EAGAIN/EWOULDBLOCK) when they cannot be fulfilled, so you don't need separate threads, but you do need a third API that tells you when the operations can be fulfilled. This is the purpose of the select() API.

  3. Asynchronous I/O, in which you schedule the transfer and are given back some kind of a handle via which you can interrogate the status of the transfer, or, in more advanced APIs, a callback.

You should certainly never use the while (in.available() > 0) / sleep() style you are using here. InputStream.available() has few correct uses and this isn't one of them, and the sleep is literally a waste of time. The data can arrive within the sleep time, and a normal read() would wake up immediately.

You should rather use a boolean variable instead of while(true) to properly close your thread when you will want to. Also yes, you should create multiple thread, one per client connected, as the thread will block itself until a new data is received (with DataInputStream().read() for example). And no, this is not really a design question, each library/Framework or languages have its own way to listen from a socket, for example to listen from a socket in Qt you should use what is called "signals and slots", not an infinite loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM