从NIO服务器发送消息

时间:2017-02-09 11:46:37

标签: java sockets nio

以下代码成功创建服务器并接受传入客户端。

package socket;

import java.nio.*;
import java.nio.channels.*;
import java.net.*;
import java.util.*;
import java.io.IOException;

public class NonBlockingServer {

    public static void main(String[] args) throws InterruptedException, IOException {

        // Create a new Thread
        Server s = new Server();
        new Thread(s).start();

        // Give 10 seconds for client to connect
        Thread.sleep(10000);

// This Doesn't work?

        s.Write("Hello, Client!");

        System.out.println("Done");
    }
}

//A class which implements Runnable Interface
class Server implements Runnable  {

    SocketChannel AcceptedClient;
    ServerSocketChannel serverChannel;
    Selector selector;

    void Write(String s) throws IOException {
        ByteBuffer buffer = ByteBuffer.allocate(s.length());
        buffer.put(s.getBytes());

        int numWrite = -1;
        numWrite = AcceptedClient.write(buffer);

        while (buffer.hasRemaining())
        {
            numWrite += AcceptedClient.write(buffer);
        }

        System.out.println(numWrite);
    }

    @Override
    public void run()
    {

        int port = 4041;

        System.out.println("Listening for connections on port " + port);

        try {
            // Bind the port
            serverChannel = ServerSocketChannel.open();
            ServerSocket ss = serverChannel.socket();
            InetSocketAddress address = new InetSocketAddress(port);
            ss.bind(address);

            // Non-blocking Server
            serverChannel.configureBlocking(false);

            // Register with Selector
            selector = Selector.open();
            serverChannel.register(selector, SelectionKey.OP_ACCEPT);

        } catch (IOException ex) {
            ex.printStackTrace();
            return;
        }

        while (true) {

            try {

                // Blocks until a 'socket' is ready registered with selector is ready.
                selector.select();

            } catch (IOException ex) {
                ex.printStackTrace();
                break;
            }

            Set<SelectionKey> readyKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = readyKeys.iterator();

            while (iterator.hasNext()) {

                SelectionKey key = iterator.next();
                iterator.remove();

                try {

                    if (key.isAcceptable()) {

                        ServerSocketChannel server = (ServerSocketChannel) key.channel();
                        SocketChannel client = server.accept();
                        System.out.println("Accepted connection from " + client);
                        client.configureBlocking(false);

                        // Client accepted by server can read.
                        SelectionKey key2 = client.register(selector, SelectionKey.OP_READ);

                        AcceptedClient = (SocketChannel) key2.channel();

                    }

                } catch (IOException ex) {
                    key.cancel();
                    try {
                        key.channel().close();
                    } catch (IOException cex) {
                    }
                }
            }
        }
    }
} 

但是当我尝试在连接到服务器后向客户端发送消息时,它不起作用,即客户端没有收到消息。

从服务器向特定客户端发送邮件的正确方法是什么?

我查看了互联网,但未找到任何服务器向客户端发送消息的示例。

1 个答案:

答案 0 :(得分:1)

您需要在flip()之前write()缓冲区,如果您要保留缓冲区,则需要事后compact()

注意关闭频道会取消密钥。