Почему клиент и сервер не могут одновременно писать на канал? - PullRequest
0 голосов
/ 15 марта 2020
//server code
public class BlockingServer_WriteToSocket {
    public static void main(String[] args) throws IOException {
        ServerSocketChannel ssChannel = ServerSocketChannel.open();
        ssChannel.bind(new InetSocketAddress(9898));
        FileChannel inChannel = FileChannel.open(Paths.get("1.jpg"), StandardOpenOption.READ);

        SocketChannel sChannel = ssChannel.accept();
        System.out.println("BlockingServer accept");
        ByteBuffer buf = ByteBuffer.allocate(1024);
        System.out.println("befor loop");
        int i = 1;
        while (inChannel.read(buf) != -1) {
            System.out.println("BlockingServer write to channel "+ i++ + " "+new SimpleDateFormat("yyyy/MM/dd-HH:mm:ss:SSS").format(new Date()));
            buf.flip();
            sChannel.write(buf);
            buf.clear();
        }
        System.out.println("already get data, and output to local file");

        sChannel.close();
        inChannel.close();
        ssChannel.close();
    }
}

//client code
public class BlockingClient_WriteToSocket {
    public static void main(String[] args) throws IOException {
        SocketChannel sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9898));
        FileChannel inChannel = FileChannel.open(Paths.get("2.jpg"), StandardOpenOption.READ);

        ByteBuffer buf = ByteBuffer.allocate(1024);
        System.out.println("befor loop");
        int i = 1;
        while (inChannel.read(buf) != -1) {
            System.out.println("BlockingClient write to channel "+i++ + " "+new SimpleDateFormat("yyyy/MM/dd-HH:mm:ss:SSS").format(new Date()));
            buf.flip();
            sChannel.write(buf);
            buf.clear();
        }
        System.out.println("already get data, and output to local file");

        inChannel.close();
        sChannel.close();
    }
}

Затем запустите сервер и клиент один за другим. Из результатов печати вы обнаружите, что после последней записи сервера в канал, затем клиент начинает запись в канал в первый раз. НО Почему?

Наконец, поскольку сервер закрыл сокет, клиент сообщил об ошибке.

//server print
BlockingServer write to channel 52 2020/03/15-14:58:17:665
BlockingServer write to channel 53 2020/03/15-14:58:17:665
BlockingServer write to channel 54 2020/03/15-14:58:17:665
already get data, and output to local file

//client print
befor loop
BlockingClient write to channel 1 2020/03/15-14:58:17:670
BlockingClient write to channel 2 2020/03/15-14:58:17:671
Exception in thread "main" java.io.IOException: The software in your host terminated an established connection.
...