2012-06-18 32 views
3

那些讀過我以前的問題的人可能已經知道這一點:我目前正在試圖抓住整個WiFi Direct的東西。我迄今爲止所做的是創建連接。 我想要做的是通過UDP發送一個數據包到groupOwner(這是IP當然是已知的) - 但它似乎每次都會丟失。UDP數據包(通過WiFi Direct)永遠不會到達

這是我的一些代碼,我有一個服務接收文件和intentservice在後臺提交他們:

FileReceiverService.java

@Override 
    public void run() { 
     Log.d(TAG, "Thread starting..."); 
     try { 
      app.log("Opening UDP socket to receive files."); 
      DatagramSocket socket = new DatagramSocket(PORT); 
      app.log("Socket open!"); 
      socket.setSoTimeout(5000); 
      app.log("Waiting for packet.."); 
      while (isRunning && !isInterrupted()) { 
       DatagramPacket packet = new DatagramPacket(
         new byte[WiFiPacket.PACKET_SIZE], 
         WiFiPacket.PACKET_SIZE); 
       try { 
        socket.receive(packet); 
        app.log("Received " + packet.getLength() 
          + " bytes, trying to parse!"); 
        parsePacket(packet); 
       } catch (SocketTimeoutException e) { 
       } catch (Exception e) { 
        app.log("Something went wrong: " + e.getMessage()); 
        e.printStackTrace(); 
       } 
      } 
      socket.close(); 
      app.log("Closing UDP socket"); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

其中常量WiFiPacket.PACKET_SIZE設置爲1024 * 32(32千字節,因爲我收到了「ERRBLABLA MSG太長」的錯誤,值更高)。

FileTransferService.java

@Override 
protected void onHandleIntent(Intent intent) { 
    App app = (App) getApplication(); 

    Context context = getApplicationContext(); 
    boolean rightIntent = false; 
    WiFiFile file = null; 

    if (intent.getAction().equals(ACTION_SEND_TEXT)) { 
     rightIntent = true; 
     file = WiFiFile.fromText(intent.getExtras().getString(EXTRAS_TEXT)); 
    } else if (intent.getAction().equals(ACTION_SEND_FILE)) { 
     rightIntent = true; 
     file = WiFiFile.fromFile(intent.getExtras().getString(
       EXTRAS_FILE_PATH)); 
    } 
    if (rightIntent && file != null) { 

     app.getOnWiFiTransmissionChangedListener().onNewOutgoingTransfer(
       file); 
     String text = intent.getExtras().getString(EXTRAS_TEXT); 
     String host = intent.getExtras().getString(
       EXTRAS_GROUP_OWNER_ADDRESS); 
     DatagramSocket socket = null; 
     int port = intent.getExtras().getInt(EXTRAS_GROUP_OWNER_PORT); 
     Log.d(TAG, "Sending packets to " + host + ":" + port); 
     try { 
      socket = new DatagramSocket(); 
      int bytesSent = 0; 
      for (WiFiPacket p : file) { 
       Log.d(TAG, "Preparing another packet.."); 
       byte[] payload = p.getBytes(); 
       DatagramPacket packet = new DatagramPacket(payload, 
         payload.length, InetAddress.getByName(host), port); 
       Log.d(TAG, "Sending packet.."); 
       socket.send(packet); 
       bytesSent += payload.length; 
       Log.d(TAG, "Packet send! Contained " + payload.length 
         + " bytes! All over we've sent about " + bytesSent 
         + " bytes!"); 
       List<WiFiFile> list = new ArrayList<WiFiFile>(); 
       list.add(file); 
       app.getOnWiFiTransmissionChangedListener() 
         .onTransferProgressChanged(list); 
      } 

      app.getOnWiFiTransmissionChangedListener() 
        .onFileTransferSuccessful(file); 

      Log.d(TAG, "Client: Data written"); 
     } catch (IOException e) { 
      e.printStackTrace(); 
      Log.e(TAG, e.getMessage()); 
     } finally { 
      if (socket != null) { 
       if (socket.isConnected()) { 
        socket.close(); 
       } 
      } 
     } 

    } 
} 

的代碼可能不是最好的,但是對於現在我關心的唯一事情就是接受這個該死的包。 :)

您的信息:我將類WiFiFile的實例分成WiFiPackets不超過PACKET_SIZE限制,因此包含某種自己的頭文件信息有關文件的偏移量,總長度,發件人(用戶名/ inetaddress)和類似的東西。 我的日誌記錄告訴我發送了大約25KB的字節,socket.send不會拋出任何錯誤,而是調用我的偵聽器(也告訴我傳輸已完成)。 據我所知,UDP數據包很容易丟失,但我已經嘗試了大約10次,我認爲25KB數據包丟失的概率非常小。

你看到我失蹤的任何東西嗎?幾個小時後,我正在盯着我的代碼,試圖找出它,並在其中放入越來越多的調試/日誌語句,但沒有任何進展。

謝謝!

PS:

IP地址和端口是正確的。

PS2:

AndroidManifest.xml中

<uses-feature 
    android:name="android.hardware.wifi.direct" 
    android:required="true" /> 

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> 
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> 
<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
<uses-permission android:name="android.permission.GET_ACCOUNTS" /> 
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" /> 
<uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" /> 

回答

7

好吧,我解決了這個問題。 我在收到創建成功組創建的回調後直接發送了消息,認爲組真的會「準備就緒」...通過在TimerTask中發送一個初始消息,每〜200-500毫秒解決此問題,之後取消任務接收確認。 希望這可以幫助你們中的一些人,面對同樣的問題。 :)