2012-05-19 100 views
0

使用NIO,我們將兩個端口綁定到ServerSocket類。使用NIO的套接字中客戶端的IP地址

 serverChannelPrimary = ServerSocketChannel.open(); 
     serverChannelSecondary = ServerSocketChannel.open(); 

     // Retrieves a server socket associated with this channel 
     serverSocketPrimary = serverChannelPrimary.socket(); 
     serverSocketSecondary = serverChannelSecondary.socket(); 

     // Opens a connection selector 
     connectionSelector = Selector.open(); 

     // Bind the specified port num 
     serverSocketPrimary.bind(new InetSocketAddress(portOne)); 
     serverSocketSecondary.bind(new InetSocketAddress(portTwo)); 

     // Set nonblocking mode for the listening socket 
     serverChannelPrimary.configureBlocking(false); 
     serverChannelSecondary.configureBlocking(false); 

     // Register the ServerSocketChannel with the Selector 
     serverChannelPrimary.register(connectionSelector, SelectionKey.OP_ACCEPT); 
     serverChannelSecondary.register(connectionSelector, SelectionKey.OP_ACCEPT); 

現在,我們還能夠獲取時,新的客戶端發出的第一個請求,我們將添加到一個矢量clientIps所連接的客戶端的IP地址。

while (isActive) { 
     try { 
      numberOfKeys = 0; 
      numberOfKeys = connectionSelector.select(timeOut); 
      if (numberOfKeys == 0) { 
       continue; // None of request available 
      } 
      // Get iterator through the selected keys list 
      Iterator<SelectionKey> iterKeys = connectionSelector 
        .selectedKeys().iterator(); 
      while (iterKeys.hasNext()) { 
       try { 
        SelectionKey selectedKey = (SelectionKey) iterKeys 
          .next(); 
        // Verify the key validity 
        if (!selectedKey.isValid()) { 
         logger.error("Received key is invalid"); 
         continue; 
        } else if (selectedKey.isAcceptable()) { 
         // Accept the client request 
         ServerSocketChannel server = (ServerSocketChannel) selectedKey 
           .channel(); 
         SocketChannel channel = server.accept(); 
         // Get the socket associated with this channel 
         Socket clientInfo = channel.socket(); 
         logger.debug("Application got client request from (Host name:" 
           + clientInfo.getInetAddress().getHostName() 
           + ",Ip address:" 
           + clientInfo.getInetAddress() 
             .getHostAddress() 
           + ",port:" 
           + clientInfo.getPort()); 

         String clientAddress=clientInfo.getInetAddress().getHostAddress(); 
         if(!clientIps.contains(clientAddress)){ 
          clientIps.add(clientAddress); 
         } 

         logger.debug("List of client : "+clientIps); 

         clientMgr.includeClient(channel); 
        } 
       } catch (Exception e) { 
        logger.error(e.getMessage()); 
       } finally { 
        logger.debug("Since this key has been handled, remove the SelectedKey from the selector list."); 
        iterKeys.remove(); 
       } 

      } 

     } catch (Exception e) { 
      logger.error(e.getMessage()); 
     } 
    } 

然而,連接已建立後,一旦我們開始從兩個端口多個客戶端獲取數據,是有可能確定,每個客戶的IP地址,只要每個客戶端發送數據。我希望我提供的代碼足以說明我們所處的情況。

+0

您已將ServerSocketChannel的兩個實例綁定到兩個不同的端口。 – EJP

回答

1

ServerSocketChannel是TCP,所以兩端的IP地址不能更改。

在您的線路

SocketChannel channel = server.accept(); 

信道是專用於特定的客戶端。這些是您將用於與每個客戶端進行通信的對象,每個對象都代表一個單個遠程ip /端口元組的TCP會話。

1

您可以撥打SocketChannel.socket().getSocketAddress()來獲取任何特定SocketChannel的遠程地址。

+0

Java 7允許將其簡化爲SocketChannel.getSocketAddress()! –

0

一旦你得到socketChannel能夠發送回客戶端,你可以使用下面的函數。

//Not complete example 
SocketChannel ssc; 
/* after accepting and other such required operations */ 

ssc.socket().getInetAddress().toString(); 
/** 
Returns: 
the remote IP address to which this socket is connected, or null if the socket is not connected. 

will return 10.50.10.20 as a string 
*/ 

//To get remote port as an int 
ssc.socket().getPort(); 
相關問題