2015-07-10 62 views
0

我想在兩個設備,服務器和客戶端之間傳輸文件..我在客戶端有一個小問題。 我在logcat中得到這個錯誤:傳輸2安卓設備之間的文件

java.lang.ArrayIndexOutOfBoundsException: length=1024; regionStart=0; regionLength=-1 

請,如果我的代碼是錯誤的告訴我。我想創建一個應用程序,並且我正在進行轉換的4天。它讓我感到可怕。請幫助

這是客戶端:

package com.example.test; 


import java.io.BufferedOutputStream; 
import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.net.Socket; 
import android.support.v7.app.ActionBarActivity; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.TextView; 
import android.widget.Toast; 
import android.os.Bundle; 
import android.os.Environment; 

public class MainActivity extends ActionBarActivity { 

    EditText editTextAddress; 
    Button buttonConnect; 
    TextView textPort; 

    static final int SocketServerPORT = 8000; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     editTextAddress = (EditText) findViewById(R.id.address); 
     textPort = (TextView) findViewById(R.id.port); 
     textPort.setText("port: " + SocketServerPORT); 
     buttonConnect = (Button) findViewById(R.id.connect); 

     buttonConnect.setOnClickListener(new OnClickListener(){ 

       @Override 
       public void onClick(View v) { 
       ClientRxThread clientRxThread = 
       new ClientRxThread(
         editTextAddress.getText().toString(), 
         SocketServerPORT); 

       clientRxThread.start(); 
       }}); 
    } 

    private class ClientRxThread extends Thread { 
     String dstAddress; 
     int dstPort; 

     ClientRxThread(String address, int port) { 
      dstAddress = address; 
      dstPort = port; 
     } 

     @Override 
     public void run() { 
      Socket socket = null; 

      try { 
       socket = new Socket(dstAddress, dstPort); 

       File file = new File(
         Environment.getExternalStorageDirectory(), 
         "input.jpg"); 

       byte[] bytes = new byte[1024]; 
       InputStream is = socket.getInputStream(); 
       FileOutputStream fos = new FileOutputStream(file); 
       BufferedOutputStream bos = new BufferedOutputStream(fos); 
       int bytesRead = is.read(bytes, 0, bytes.length); 
       bos.write(bytes, 0, bytesRead); 
       bos.close(); 
       socket.close(); 

       MainActivity.this.runOnUiThread(new Runnable() { 

         @Override 
         public void run() { 
         Toast.makeText(MainActivity.this, 
           "Finished", 
           Toast.LENGTH_LONG).show(); 
         }}); 

      } catch (IOException e) { 

       e.printStackTrace(); 

       final String eMsg = "Something wrong: " + e.getMessage(); 
       MainActivity.this.runOnUiThread(new Runnable() { 

         @Override 
         public void run() { 
         Toast.makeText(MainActivity.this, 
           eMsg, 
           Toast.LENGTH_LONG).show(); 
         }}); 

      } finally { 
       if(socket != null){ 
        try { 
         socket.close(); 
        } catch (IOException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 
       } 
      } 
     } 
    } 

} 

客戶端的XML:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical" 
android:paddingBottom="@dimen/activity_vertical_margin" 
android:paddingLeft="@dimen/activity_horizontal_margin" 
android:paddingRight="@dimen/activity_horizontal_margin" 
android:paddingTop="@dimen/activity_vertical_margin" 
tools:context="com.example.androidsocketfiletransferclient.MainActivity" > 

<TextView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_gravity="center_horizontal" 
    android:autoLink="web" 
    android:text="http://android-er.blogspot.com/" 
    android:textStyle="bold" /> 

<TextView 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:text="File Transfer Client" 
    android:textStyle="bold" /> 

<EditText 
    android:id="@+id/address" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:hint="dstAddress" /> 

<TextView 
    android:id="@+id/port" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" /> 

<Button 
    android:id="@+id/connect" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:text="Connect..." /> 

客戶機清單:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
package="com.example.test" 
android:versionCode="1" 
android:versionName="1.0" > 

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

<uses-permission android:name="android.permission.INTERNET" > 
</uses-permission> 

<uses-sdk 
    android:minSdkVersion="8" 
    android:targetSdkVersion="19" /> 

<application 
    android:allowBackup="true" 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" 
    android:theme="@style/AppTheme" > 
    <activity 
     android:name="com.example.test.MainActivity" 
     android:label="@string/app_name" > 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
</application> 

服務器:

package com.example.testserverandroid; 

import java.io.BufferedInputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.IOException; 
import java.io.OutputStream; 
import java.net.InetAddress; 
import java.net.NetworkInterface; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.net.SocketException; 
import java.util.Enumeration; 
import android.support.v7.app.ActionBarActivity; 
import android.os.Bundle; 
import android.os.Environment; 
import android.widget.TextView; 
import android.widget.Toast; 

public class MainActivity extends ActionBarActivity { 

TextView infoIp, infoPort; 

static final int SocketServerPORT = 8000; 
ServerSocket serverSocket; 

ServerSocketThread serverSocketThread; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    infoIp = (TextView) findViewById(R.id.infoip); 
    infoPort = (TextView) findViewById(R.id.infoport); 

    infoIp.setText(getIpAddress()); 

    serverSocketThread = new ServerSocketThread(); 
    serverSocketThread.start(); 
} 

@Override 
protected void onDestroy() { 
    super.onDestroy(); 

    if (serverSocket != null) { 
     try { 
      serverSocket.close(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

private String getIpAddress() { 
    String ip = ""; 
    try { 
     Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface 
       .getNetworkInterfaces(); 
     while (enumNetworkInterfaces.hasMoreElements()) { 
      NetworkInterface networkInterface = enumNetworkInterfaces 
        .nextElement(); 
      Enumeration<InetAddress> enumInetAddress = networkInterface 
        .getInetAddresses(); 
      while (enumInetAddress.hasMoreElements()) { 
       InetAddress inetAddress = enumInetAddress.nextElement(); 

       if (inetAddress.isSiteLocalAddress()) { 
        ip += "SiteLocalAddress: " 
          + inetAddress.getHostAddress() + "\n"; 
       } 

      } 

     } 

    } catch (SocketException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     ip += "Something Wrong! " + e.toString() + "\n"; 
    } 

    return ip; 
} 

public class ServerSocketThread extends Thread { 

    @Override 
    public void run() { 
     Socket socket = null; 

     try { 
      serverSocket = new ServerSocket(SocketServerPORT); 
      MainActivity.this.runOnUiThread(new Runnable() { 

       @Override 
       public void run() { 
        infoPort.setText("I'm waiting here: " 
          + serverSocket.getLocalPort()); 
       } 
      }); 

      while (true) { 
       socket = serverSocket.accept(); 
       FileTxThread fileTxThread = new FileTxThread(socket); 
       fileTxThread.start(); 
      } 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } finally { 
      if (socket != null) { 
       try { 
        socket.close(); 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 

} 

public class FileTxThread extends Thread { 
    Socket socket; 

    FileTxThread(Socket socket) { 
     this.socket = socket; 
    } 

    @Override 
    public void run() { 
     File file = new File(Environment.getExternalStorageDirectory(), 
       "test.txt"); 

     byte[] bytes = new byte[(int) file.length()]; 
     BufferedInputStream bis; 
     try { 
      bis = new BufferedInputStream(new FileInputStream(file)); 
      bis.read(bytes, 0, bytes.length); 
      OutputStream os = socket.getOutputStream(); 
      os.write(bytes, 0, bytes.length); 
      os.flush(); 
      socket.close(); 

      final String sentMsg = "File sent to: " 
        + socket.getInetAddress(); 
      MainActivity.this.runOnUiThread(new Runnable() { 

       @Override 
       public void run() { 
        Toast.makeText(MainActivity.this, sentMsg, 
          Toast.LENGTH_LONG).show(); 
       } 
      }); 

     } catch (FileNotFoundException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } finally { 
      try { 
       socket.close(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 

    } 
} 
} 

服務器清單:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
package="com.example.test" 
android:versionCode="1" 
android:versionName="1.0" > 

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

<uses-permission android:name="android.permission.INTERNET" > 
</uses-permission> 

<uses-sdk 
    android:minSdkVersion="8" 
    android:targetSdkVersion="19" /> 

<application 
    android:allowBackup="true" 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" 
    android:theme="@style/AppTheme" > 
    <activity 
     android:name="com.example.test.MainActivity" 
     android:label="@string/app_name" > 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
</application> 

+0

後堆棧跟蹤。 –

回答

0

在你的客戶,當你從輸入流中讀取,讀取的將是字節數-1,如果你已經在流的末尾。這在documentation for InputStream中描述。

執行此語句時發生ArrayIndexOutOfBoundsException異常,並且bytesRead爲-1。

bos.write(bytes, 0, bytesRead); 

您需要重構客戶端代碼以讀取輸入流以檢查流結束。

替換此:

int bytesRead = is.read(bytes, 0, bytes.length); 
bos.write(bytes, 0, bytesRead); 

有了這個:包含ArrayIndexOutOfBoundsException異常

int bytesRead; 
while ((bytesRead = is.read(bytes)) > 0) { 
    bos.write(bytes, 0, bytesRead); 
} 
+0

謝謝你的明確答案 –