2012-07-16 56 views
0

我正在開發一款應用程序,它將充當服務器,這就是將會有一臺平板電腦將成爲「服務器」,並且會有其他平板電腦將連接到「服務器」。 我想用一個選擇器來使用java NIO來保存線程。但我的問題是,我有一個在android中的線程運行的java代碼,但是當線程運行時,它不會發生任何事情。在客戶端,它給出和拒絕連接的例外。 代碼在java應用程序中運行,但在android中不運行。Java TCP服務器NIO與Android中的選擇器

我也有互聯網許可。

的java的選擇:

Thread t = new Thread(new Runnable() { 

    private Selector   selector; 
    private ServerSocketChannel sChan; 
    private List<SocketChannel> sockets; 

    public void run() { 

     try { 
      selector = SelectorProvider.provider().openSelector(); 
      sChan = ServerSocketChannel.open(); 
      InetSocketAddress iaddr = new InetSocketAddress(InetAddress.getLocalHost(), 8000); 

      sChan.configureBlocking(false); 
      sChan.socket().bind(iaddr); 

      System.out.println("Running on port:" + sChan.socket().getLocalPort()); 

      sChan.register(selector, SelectionKey.OP_ACCEPT); 
      sockets = new LinkedList<SocketChannel>(); 

     } 
     catch (IOException e) { 
      e.printStackTrace(); 
     } 

     Iterator<SelectionKey> it; 

     try { 
      while (true) { 
       selector.select(); 

       it = selector.selectedKeys().iterator(); 
       while (it.hasNext()) { 
        SelectionKey key = it.next(); 

        it.remove(); 
        if (!key.isValid()) { 
         continue; 
        } 

        // Finish connection in case of an error 
        if (key.isConnectable()) { 
         SocketChannel ssc = (SocketChannel) key.channel(); 
         if (ssc.isConnectionPending()) { 
          ssc.finishConnect(); 
         } 
        } 

        if (key.isAcceptable()) { 
         ServerSocketChannel ssc = (ServerSocketChannel) key.channel(); 
         SocketChannel newClient = ssc.accept(); 

         newClient.configureBlocking(false); 
         newClient.register(selector, SelectionKey.OP_READ); 
         sockets.add(newClient); 

         System.out.println("new client: " + newClient.socket().getInetAddress().getHostAddress()); 
        } 

        if (key.isReadable()) { 
         SocketChannel sc = (SocketChannel) key.channel(); 
         ByteBuffer data = ByteBuffer.allocate(sc.socket().getSendBufferSize()); 

         System.out.println("new message: " + sc.socket().getInetAddress().getHostAddress()); 

         if (sc.read(data) == -1) { 
          continue; 
         } 

         data.flip(); 

         Teste m = (Teste) UdpUtil.byteToMessage(data.array()); 

         System.out.println("message: " + m); 
         System.out.println("\n\n" + m.cenas); 
         sc.close(); 
        } 
       } 
      } 
     } 
     catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
}); 
t.start(); 

和客戶端應用程序:

InetSocketAddress isa = new InetSocketAddress(InetAddress.getByName("192.168.2.102"), 8000); 

    SocketChannel sc = null; 

    try { 

     // Connect 
     sc = SocketChannel.open(); 
     sc.connect(isa); 

     // Read the time from the remote host. For simplicity we assume 
     // that the time comes back to us in a single packet, so that we 
     // only need to read once. 

     byte[] message = UdpUtil.messageToByteMessage(new messages.Teste("hello there")); 

     ByteBuffer buf = ByteBuffer.wrap(message); 
     sc.write(buf); 
    } 
    finally { 
     // Make sure we close the channel (and hence the socket) 
     if (sc != null) { 
      sc.close(); 
     } 
} 

注:泰斯特類它只是將用作機器人之間的消息的類。

我甚至試過這code和一切順利,但與選擇器不。 我希望我自己清楚問題是什麼。

感謝提前:)

+0

這裏的實際問題是'連接被拒絕'。到目前爲止,它與NIO或選擇器完全沒有關係。 – EJP 2012-07-20 02:53:33

回答

2

刪除的第一個參數新的InetSocketAddress(),您使用綁定的ServerSocketChannel的一個。目前你只能綁定到127.0.0.1,這是其他主機無法看到的。通過省略參數綁定到0.0.0.0,這意味着'在所有接口上偵聽'。

+0

就是這樣。謝謝 ;) – 2012-07-26 15:01:32

0

確保您已要求在Android的上網權限通過進入你的AndroidManifest.xml文件,並把: 使用許可權的android:NAME =「android.permission.INTERNET對」/>

+0

噢,是的,我有這個權限;)我忘了提及;) – 2012-07-16 18:41:17

+0

如果你能夠在任何簡單的情況下實現連接,相關的問題將是。首先開始工作來驗證網絡問題可能會很好。 – 2012-07-16 18:50:04

+0

我使用了http://systembash.com/content/a-simple-java-tcp-server-and-tcp-client/的代碼,它運行良好;) – 2012-07-16 19:13:18