2010-11-02 126 views
1

我再次遇到了Android中套接字編程的問題。我的問題是Selector.select()返回零,表示沒有SocketChannel準備寫入。再次,相同的代碼在普通的Java中工作,但在Android中不起作用。這裏是我的代碼:SocketChannel還沒有準備好

package com.test; 

import java.io.IOException; 
import java.net.InetSocketAddress; 
import java.net.SocketAddress; 
import java.nio.channels.ClosedChannelException; 
import java.nio.channels.Selector; 
import java.nio.channels.SocketChannel; 

import android.app.Activity; 
import android.os.Bundle; 
import android.util.Log; 

public class WebSocketTest extends Activity { 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

    SocketChannel channel = null; 

     SocketAddress socketAdress = new InetSocketAddress("10.0.0.1", 8787); 

    try { 
    channel = SocketChannel.open(); 
    } catch (IOException e) { 
    Log.e("ERROR", "channel open"); 
    } 

    try { 
    channel.configureBlocking(false); 
    } catch (IOException e1) { 
    Log.e("ERROR", "channel blocking"); 
    } 

    try { 
    channel.connect(socketAdress); 
    } catch (IOException e) { 
    Log.e("ERROR", "channel connect"); 
    } 

    try { 
    while(!channel.finishConnect()) 
    { 

    } 
    } catch (IOException e1) { 
    Log.e("ERROR", "channel finishConnect"); 
    } 


    Selector selector = null; 
    try { 
    selector = Selector.open(); 
    } catch (IOException e) { 
    Log.e("ERROR", "selector open"); 
    } 
    try { 
    channel.register(selector, channel.validOps()); 
    } catch (ClosedChannelException e) { 
    Log.e("ERROR", "channel register"); 
    } 

    boolean i = true; 

    while(i) 
    { 
    int readyChannels = 0; 
    try { 
    readyChannels = selector.select(); 
    } catch (IOException e) { 
    Log.e("ERROR", "selector select"); 
    } 

    if(readyChannels > 0) 
    { 
    i = false; 
    } 
    } 
    } 
} 

在Java readyChannels = 1。在Android中爲0。 誰能幫助我?

+0

您是否對模擬器和設備都有這個問題? – 2010-11-02 22:27:32

回答

2

模擬器位於虛擬路由器的後面。您需要配置Network Redirections(端口轉發)以使模擬器上的某個端口對外部網絡(包括您的計算機)可見。

+0

感謝您的建議。它原來在設備上工作,但不使用模擬器。 當然,在仿真器中測試它會很好。你能向我解釋如何做這些網絡重定向嗎? – Martin 2010-11-03 16:37:59

+0

這裏全部描述:http://developer.android.com/guide/developing/tools/emulator.html#console 1.啓動模擬器2.通過telnet連接到模擬器3.執行'redir add tcp:5000:6000 '4.在6000端口上的仿真器上運行套接字軟件5.連接到本地PC上的5000端口,端口將被重定向到仿真器 – 2010-11-03 18:12:53

0

這個NIO代碼有幾個問題。

  1. 而不是連接,然後旋轉finishConnect(),可能永遠,你應該進入非阻塞模式之前連接。此刻,您只需刻錄CPU,展平電池等。

  2. 您應該只在註冊OP_WRITE時進行註冊。它通常是「準備好」的,所以如果你永久地註冊頻道,你的選擇循環就會旋轉。 OP_WRITE沒有準備好的唯一時間是當你填充套接字發送緩衝區。

+0

感謝您的建議。這有助於但不能解決問題。還沒有準備好套接字。 – Martin 2010-11-03 08:35:31

+0

聽起來像是Android中的一個bug,但是如果您之前填充了套接字發送緩衝區,則只需要OP_WRITE就可以了,即之前的write()返回了零。如果你還沒有遇到這種情況,你還沒有問題。寫吧()。 – EJP 2010-11-04 06:23:45

相關問題