2013-05-17 112 views
1

我正在實現一個套接字應用程序,其中一個手機將成爲客戶端,另一個將成爲服務器。該程序能夠使用打印作業發送字符串很好從客戶端到服務器,但是當我嘗試發送圖像文件時,它會引發異常。如果有人能幫助我,我真的很感激。Android - 通過套接字編程發送圖像

這裏是服務器

public class ServerActivity extends Activity { 

private TextView serverStatus; 
private ImageView profile; 

// DEFAULT IP 
public static String SERVERIP = "10.0.2.15"; 

// DESIGNATE A PORT 
public static final int SERVERPORT = 8080; 

private Handler handler = new Handler(); 

private ServerSocket serverSocket; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.server); 
    serverStatus = (TextView) findViewById(R.id.server_status); 
    profile = (ImageView) findViewById(R.id.image); 

    String filepath = "/sdcard/DCIM/time table.png"; 
    File imagefile = new File(filepath); 
    FileInputStream fis = null; 
     try { 
      fis = new FileInputStream(imagefile); 
     } catch (FileNotFoundException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

    Bitmap bm = BitmapFactory.decodeStream(fis); 
    profile.setImageBitmap(bm); 

    SERVERIP = getLocalIpAddress(); 

    Thread fst = new Thread(new ServerThread()); 
    fst.start(); 
} 

public class ServerThread implements Runnable { 
    //String line; 
    byte [] line; 
    Bitmap bitmap; 
    public void run() { 
     try { 
      if (SERVERIP != null) { 
       handler.post(new Runnable() { 
        @Override 
        public void run() { 
         serverStatus.setText("Listening on IP: " + SERVERIP); 
        } 
       }); 
       serverSocket = new ServerSocket(SERVERPORT); 
       while (true) { 
        // LISTEN FOR INCOMING CLIENTS 
        Socket client = serverSocket.accept(); 
        handler.post(new Runnable() { 
         @Override 
         public void run() { 
          serverStatus.setText("Connected."); 
         } 
        }); 

        try { 
         /*InputStream in = client.getInputStream(); 
         line = null; 
         in.read(line); 

          Log.d("ServerActivity", line.toString()); 
          bitmap = BitmapFactory.decodeByteArray(line , 0, line.length);*/ 
         int bytesRead; 
         int current = 0; 
         int filesize=65383; 
         byte [] mybytearray2 = new byte [filesize]; 
         InputStream is = client.getInputStream(); 
         FileOutputStream fos = new FileOutputStream("/storage/sdcard0/Pictures/Screenshots/IMG-20130112-WA0011.jpeg"); // destination path and name of file 
         //FileOutputStream fos = new FileOutputStream("/storage/sdcard0/Pictures/Screenshots/"); 
         BufferedOutputStream bos = new BufferedOutputStream(fos); 
         bytesRead = is.read(mybytearray2,0,mybytearray2.length); 
         current = bytesRead; 


         do { 
          bytesRead = 
           is.read(mybytearray2, current, (mybytearray2.length-current)); 
          if(bytesRead >= 0) current += bytesRead; 
         } while(bytesRead > -1); 

         bos.write(mybytearray2, 0 , current); 
         bos.flush(); 
         long end = System.currentTimeMillis(); 
         //System.out.println(end-start); 
         bos.close(); 


          handler.post(new Runnable() { 
           @Override 
           public void run() { 
            profile.setImageBitmap(bitmap); 

            //serverStatus.setText(line); 
           } 
          }); 

         /*BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream())); 
         line = null; 
         while ((line = in.readLine()) != null) { 
          Log.d("ServerActivity", line); 
          handler.post(new Runnable() { 
           @Override 
           public void run() { 
            serverStatus.setText(line); 
            // DO WHATEVER YOU WANT TO THE FRONT END 
            // THIS IS WHERE YOU CAN BE CREATIVE 
           } 
          }); 
         }*/ 
         break; 
        } catch (Exception e) { 
         handler.post(new Runnable() { 
          @Override 
          public void run() { 
           serverStatus.setText("Oops. Connection interrupted. Please reconnect your phones."); 
          } 
         }); 
         e.printStackTrace(); 
        } 
       } 
      } else { 
       handler.post(new Runnable() { 
        @Override 
        public void run() { 
         serverStatus.setText("Couldn't detect internet connection."); 
        } 
       }); 
      } 
     } catch (Exception e) { 
      handler.post(new Runnable() { 
       @Override 
       public void run() { 
        serverStatus.setText("Error"); 
       } 
      }); 
      e.printStackTrace(); 
     } 
    } 
} 

// GETS THE IP ADDRESS OF YOUR PHONE'S NETWORK 
private String getLocalIpAddress() { 
    try { 
     for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { 
      NetworkInterface intf = en.nextElement(); 
      for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) { 
       InetAddress inetAddress = enumIpAddr.nextElement(); 
       if (!inetAddress.isLoopbackAddress()) { return inetAddress.getHostAddress().toString(); } 
      } 
     } 
    } catch (SocketException ex) { 
     Log.e("ServerActivity", ex.toString()); 
    } 
    return null; 
} 

@Override 
protected void onStop() { 
    super.onStop(); 
    try { 
     // MAKE SURE YOU CLOSE THE SOCKET UPON EXITING 
     serverSocket.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

}

代碼這是客戶端代碼

public class ClientActivity extends Activity { 

private EditText serverIp; 

private Button connectPhones; 

private String serverIpAddress = ""; 

private boolean connected = false; 

private Handler handler = new Handler(); 

private Socket socket; 

private ImageView profile; 

private byte [] imgbyte; 
String filepath; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.client); 

    serverIp = (EditText) findViewById(R.id.server_ip); 
    connectPhones = (Button) findViewById(R.id.connect_phones); 
    connectPhones.setOnClickListener(connectListener); 
    profile = (ImageView) findViewById(R.id.imageView1); 

    filepath = "/sdcard/small.jpg"; 
    File imagefile = new File(filepath); 
    FileInputStream fis = null; 
     try { 
      fis = new FileInputStream(imagefile); 
     } catch (FileNotFoundException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

    Bitmap bm = BitmapFactory.decodeStream(fis); 
    imgbyte = getBytesFromBitmap(bm); 
    profile.setImageBitmap(bm); 
} 

private OnClickListener connectListener = new OnClickListener() { 

    @Override 
    public void onClick(View v) { 
     if (!connected) { 
      serverIpAddress = serverIp.getText().toString(); 
      if (!serverIpAddress.equals("")) { 
       Thread cThread = new Thread(new ClientThread()); 
       cThread.start(); 
      } 
     } 
    } 
}; 

public class ClientThread implements Runnable { 

    public void run() { 
     try { 
      InetAddress serverAddr = InetAddress.getByName(serverIpAddress); 
      Log.d("ClientActivity", "C: Connecting..."); 
      socket = new Socket(serverAddr, ServerActivity.SERVERPORT); 
      connected = true; 
      while (connected) { 
       try { 


        /*File myFile = new File (filepath); 
        byte [] mybytearray = new byte [(int)myFile.length()]; 
        FileInputStream fis = new FileInputStream(myFile); 
        BufferedInputStream bis = new BufferedInputStream(fis); 
        bis.read(mybytearray,0,mybytearray.length); 
        OutputStream os = socket.getOutputStream(); 
        Log.d("ClientActivity", "C: Sending command."); 
        //System.out.println("Sending..."); 
        os.write(mybytearray,0,mybytearray.length); 
        os.flush();*/ 

        Log.d("ClientActivity", "C: Sending command."); 
        /*PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket 
           .getOutputStream())), true);*/ 
         // WHERE YOU ISSUE THE COMMANDS 

        OutputStream output = socket.getOutputStream(); 
        Log.d("ClientActivity", "C: image writing."); 
        output.write(imgbyte); 
        output.flush(); 
         // out.println("Hey Server!"); 
         Log.d("ClientActivity", "C: Sent."); 
       } catch (Exception e) { 
        Log.e("ClientActivity", "S: Error", e); 
       } 
      } 
      socket.close(); 
      Log.d("ClientActivity", "C: Closed."); 
     } catch (Exception e) { 
      Log.e("ClientActivity", "C: Error", e); 
      connected = false; 
     } 
    } 
} 

protected void onStop() { 
    super.onStop(); 
    try { 
     // MAKE SURE YOU CLOSE THE SOCKET UPON EXITING 
     socket.close(); 
     connected = false; 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

public byte[] getBytesFromBitmap(Bitmap bitmap) { 
    ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
    bitmap.compress(CompressFormat.JPEG, 70, stream); 
    return stream.toByteArray(); 
} 

}

更新: 的例外是在拋出服務器端代碼。它的例外是:「糟糕,連接中斷,請重新連接手機。」 這是拋出的異常: 了java.lang.RuntimeException:無法創建內螺紋處理程序尚未調用Looper.prepare()

+1

拋出了什麼異常? – Logan

+1

日誌輸出?你需要發佈更多的細節。 – cbrulak

+0

我已經發布了引發異常的細節。請看看它是否有意義。 –

回答

3

謝謝大家,我發現的錯誤。 Toast消息必須位於UI線程或處理程序中。由於我在非UI線程中使用了其中的一些,它開始拋出異常。