简体   繁体   English

如何在Java Nio中将客户端的同一实例用于多个消息

[英]how to use same instance of client for multiple message in Java Nio

I am using Java Nio for Client server communication below are the code of client as well as server. 我正在使用Java Nio进行客户端服务器通信,以下是客户端和服务器的代码。

server: 服务器:

public class BufferChannelExample {
    private static String clientChannel = "clientChannel";
    private static String serverChannel = "serverChannel";
    private static String channelType = "channelType";
    private static Selector selector = null;
    static BufferChannelExample bufferChannelExample = null;
    static int port1 = 1114;
    //static String localhost1 = "192.168.1.35";
    static String localhost1 = "192.168.1.88";
    ByteBuffer buffer;
    static String msgFromClient = "";
    static MsgSaver msgSaver;
    public static void main(String[] args) {

//      readFileChannel();
        //msgSaver = new MsgSaver();
        bufferChannelExample = new BufferChannelExample();
        serverSocketExample();

    }

    public static void writeToChannels() {

        if(selector == null)
            return;
        if(!selector.isOpen())
            return;
        Set multipleKeys = selector.keys(); 
        System.out.println("multipleKeys.size() : "+multipleKeys.size());
        for (int i = 0; i < multipleKeys.size(); i++) {
            System.out.println("multipleKeys: "+multipleKeys.toString());
        }

        MulticastSocket multicastSocket = null;

        try {
            multicastSocket = new MulticastSocket(port1);

        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        Iterator<SelectionKey> mkIterator = multipleKeys.iterator();
        while (mkIterator.hasNext()) {
            SelectionKey sKey = mkIterator.next();

            //                                  System.out.println("mk rAddr : "+((SocketChannel)sKey.channel()).getRemoteAddress().toString());
            //                                  if(sKey == key){
//          if((sKey.readyOps() & SelectionKey.OP_ACCEPT) != SelectionKey.OP_ACCEPT){
            if(((Map<?, ?>) sKey.attachment()).get(channelType).equals(
                    clientChannel)){
                 System.out.println("isWritable() --- > "+sKey.isWritable());
                 System.out.println("RemoteSocketAddress : "+((SocketChannel)sKey.channel()).socket().getRemoteSocketAddress());
                // write something to the new created client
                 CharBuffer buffer;
                 if(msgFromClient.equalsIgnoreCase(""))
                 {
                  buffer = CharBuffer.wrap("Hello client new!!! ---stop");
                  System.out.println("if--");
                 }
                 else {

                     Iterator iter = multipleKeys.iterator();
                     while (iter.hasNext()) {
                       System.out.println(iter.next());
                     }

                      buffer = CharBuffer.wrap(msgFromClient);
                      System.out.println("else--");

                }

                //System.out.println("msgFromClient----"+msgSaver.getMsg());
                while (buffer.hasRemaining()) {

                    try {
                        ((SocketChannel)sKey.channel()).write(Charset.defaultCharset()
                                .encode (buffer)); 
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                buffer.clear();         
            }
            //                                  }
        }

    }

    private static void serverSocketExample() {
        ArrayList<String> remoteAddressArray = new ArrayList<String>();
        ServerSocketChannel channel1;
        try { 
            channel1 = ServerSocketChannel.open();
            channel1.socket().bind(new InetSocketAddress(localhost1, port1));
            channel1.configureBlocking(false);

            // create a selector that will by used for multiplexing. The selector
            // registers the socketserverchannel as
            // well as all socketchannels that are created
            selector = Selector.open();

            // register the serversocketchannel with the selector. The OP_ACCEPT
            // option marks
            // a selection key as ready when the channel accepts a new connection.
            // When the
            // socket server accepts a connection this key is added to the list of
            // selected keys of the selector.
            // when asked for the selected keys, this key is returned and hence we
            // know that a new connection has been accepted.
            SelectionKey socketServerSelectionKey = channel1.register(selector,
                    SelectionKey.OP_ACCEPT);
            // set property in the key that identifies the channel
            // Map<String, String=""> properties = new HashMap<string, string="">();
            Map<String, String> properties = new HashMap<String, String>();
            properties.put(channelType, serverChannel);
            socketServerSelectionKey.attach(properties);
            // wait for the selected keys
            for (;;) {
//              System.out.println("waiting for keys");
                // the select method is a blocking method which returns when atleast
                // one of the registered
                // channel is selected. In this example, when the socket accepts a
                // new connection, this method
                // will return. Once a socketclient is added to the list of
                // registered channels, then this method
                // would also return when one of the clients has data to be read or
                // written. It is also possible to perform a nonblocking select
                // using the selectNow() function.
                // We can also specify the maximum time for which a select function
                // can be blocked using the select(long timeout) function.
                if (selector.select() == 0)
                    continue;
                // the select method returns with a list of selected keys
                Set<SelectionKey> selectedKeys = selector.selectedKeys();
                Iterator<SelectionKey> iterator = selectedKeys.iterator();
                while (iterator.hasNext()) {
                    SelectionKey key = iterator.next();
//                  System.out.println("SelectionKey "+key.toString());
                    // the selection key could either by the socketserver informing
                    // that a new connection has been made, or
                    // a socket client that is ready for read/write
                    // we use the properties object attached to the channel to find
                    // out the type of channel.
                    if (((Map<?, ?>) key.attachment()).get(channelType).equals(
                            serverChannel)) {
                        // a new connection has been obtained. This channel is
                        // therefore a socket server.
                        ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key
                                .channel();
                        // accept the new connection on the server socket. Since the
                        // server socket channel is marked as non blocking
                        // this channel will return null if no client is connected.
                        SocketChannel clientSocketChannel = serverSocketChannel
                                .accept();

                        if (clientSocketChannel != null) {
                            // set the client connection to be non blocking
                            clientSocketChannel.configureBlocking(false);
                            SelectionKey clientKey = clientSocketChannel.register(
                                    selector, SelectionKey.OP_READ| SelectionKey.OP_WRITE);
                            Map<String, String> clientproperties = new HashMap<String, String>();
                            clientproperties.put(channelType, clientChannel);
                            clientKey.attach(clientproperties);

                            // write something to the new created client
                            CharBuffer buffer = CharBuffer.wrap("Hello client from server");
                            while (buffer.hasRemaining()) {
//                              clientSocketChannel.write(Charset.defaultCharset()
//                                      .encode(buffer));

                                clientSocketChannel.write(Charset.defaultCharset()
                                        .encode(buffer));

                            }
                            buffer.clear();
                        }

                    } else {
                        // data is available for read
                        // buffer for reading
                        ByteBuffer buffer = ByteBuffer.allocate(100); 
                        SocketChannel clientChannel = (SocketChannel) key.channel();    
                        int bytesRead = 0;
                        if (key.isReadable()) {
                            // the channel is non blocking so keep it open till the
                            // count is >=0
                            if ((bytesRead = clientChannel.read(buffer)) > 0) {
                                buffer.flip();
//                              System.out.println("message from client ---> "+Charset.defaultCharset().decode(
//                                      buffer));
                                msgFromClient = Charset.defaultCharset().decode(buffer).toString();
                                //msgSaver.setMsg(Charset.defaultCharset().decode(buffer).toString());
                                System.out.println("msgFromClient111----"+Charset.defaultCharset().decode(buffer).toString());
                                writeToChannels(); 
//                              if(th == null){
//                               th = new Thread(new NewRunnable());
//                               th.start();
//                              }

                                 buffer.clear();
                            }
                            if (bytesRead < 0) {
                                // the key is automatically invalidated once the
                                // channel is closed
                                clientChannel.close();
                            }
                        }

                    }

                    // once a key is handled, it needs to be removed
                    iterator.remove();

                }

            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    static Thread th = null;




}



}

Client: 客户:

public class ExampleClient2 { 公共类ExampleClient2 {

public static void main(String[] args) throws IOException,
InterruptedException {
    int port = 1114;
    SocketChannel channel = SocketChannel.open();


    // we open this channel in non blocking mode
    channel.configureBlocking(false);
    channel.connect(new InetSocketAddress("192.168.1.88", port));

    if(!channel.isConnected())
    {
        while (!channel.finishConnect()) {
            System.out.println("still connecting");
        }
    }
    System.out.println("connected...");


    while (true) {
        // see if any message has been received
        ByteBuffer bufferA = ByteBuffer.allocate(60);
        int count = 0;
        String message = "";
        while ((count = channel.read(bufferA)) > 0) {
            // flip the buffer to start reading
            bufferA.flip();
            message += Charset.defaultCharset().decode(bufferA);

        }

        if (message.length() > 0) {
            System.out.println("message " + message); 
            if(message.contains("stop"))
            {
                System.out.println("Has stop messages");
                //                  break;
            }
            else
            {
                // write some data into the channel
                CharBuffer buffer = CharBuffer.wrap("Hello Server stop from client2 from 88");
                while (buffer.hasRemaining()) {
                    channel.write(Charset.defaultCharset().encode(buffer));
                }
            }
            message = "";
        }

    }
}

} }

here if i request to server from the same client twice , server will treat as a new client and create a new connections.How to detect that the message is coming from old client and do not need to create new connections. 如果我两次从同一个客户端请求服务器,则服务器将被视为新客户端并创建新连接。如何检测消息来自旧客户端,而无需创建新连接。

thanks. 谢谢。

You can introduce HTTP Session management in your application and then track each client request based on the Session ID. 您可以在应用程序中引入HTTP会话管理,然后根据会话ID跟踪每个客户端请求。 Then you can have your application adapt to the situation. 然后,您可以让您的应用程序适应这种情况。

If your server uses Servlet technology it will be much easier in adding a Servlet filter to intercept all incoming requests. 如果您的服务器使用Servlet技术,则添加Servlet过滤器以拦截所有传入请求将更加容易。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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