读/写java服务器套接字的最佳实践

Sch*_*fty 7 java sockets networking

如何设计一个在单个插槽上运行的读写循环(支持并行读写操作)?我必须使用多个线程吗?我的(java)解决方案有什么用吗?睡眠命令怎么样?你如何在这样的循环中使用它?

我正在尝试使用2个线程:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

读取无法提供正确的结果,因为没有发送-1.我该如何解决这个问题?

这个睡眠/写循环是一个很好的解决方案吗?

use*_*421 4

进行网络 I/O 的方式基本上有以下三种:

  1. 阻塞。在这种模式下,读取和写入将被阻塞,直到它们被完成为止,因此如果您想同时执行这两个操作,则需要为每个读取和写入单独的线程。

  2. 非阻塞。在此模式下,当读取和写入无法完成时,读取和写入将返回零(Java)或在某些语言(C)中返回状态指示(return == -1,errno=EAGAIN/EWOULDBLOCK),因此您不需要单独的线程,但您确实需要第三个 API 来告诉您何时可以完成操作。这就是 API 的目的select()

  3. 异步 I/O,您可以在其中安排传输并返回某种句柄,通过该句柄您可以询问传输的状态,或者在更高级的 API 中,返回一个回调。

绝对不应该使用此处使用的while (in.available() > 0)/样式。几乎没有正确的用途,这不是其中之一,而且睡眠实际上是浪费时间。数据可以在睡眠时间内到达,正常的会立即醒来。sleep()InputStream.available()read()