2017-02-12 33 views
0

我对Android很陌生,我有一个任务来打开TCP套接字并侦听特定的端口。 客户端应用程序应该向我发送2个图像和一个彼此相关的字符串,因此我们不考虑将每个数据单独发送,而是考虑将所有数据放入json对象并发送此对象。 我的问题是,我如何解析这个JSON到保存2个图像和一个字符串? 所以这个JSON应该是这样的:Android - 如何通过套接字使用复杂对象

data 
{ 
    FileName: "some string", 
    Image1: "Image encoded with encode base64", 
    Image2: "Image encoded with encode base64" 
} 

我使用的AsyncTask所以这里是我得到的套接字数据代码:

public class DataRecord 
{ 
    String Image1; 
    String Image2; 
    String FileName; 
} 


protected DataRecord doInBackground(Socket... sockets) { 
DataRecord dataRecord = null; 

if (isExternalStorageWritable() && sockets.length > 0) { 
    Socket socket = sockets[0]; 

    dataRecord = socket.getOutputStream(); // how to extract the data from the socket into this object ??? 

    File file = new File(Environment.getExternalStorageDirectory(), dataRecord.FileName); 

    byte[] bytes = new byte[(int) file.length()]; 
    BufferedInputStream inputStream; 
    try { 
     inputStream = new BufferedInputStream(new FileInputStream(file)); 
     inputStream.read(bytes, 0, bytes.length); 

     OutputStream outputStream = dataRecord.Image1; 
     outputStream.write(bytes, 0, bytes.length); 
     outputStream.flush(); 

     socket.close(); 
    } 
    catch (Exception e) { } 
    finally { 
     try { 
      socket.close(); 
     } catch (IOException e) { } 
    } 
} 
return dataRecord; 
} 

,我需要怎么得来的套接字对象并从中提取对象以将2张图像保存到SD卡并将该字符串提取到UI。

+0

对不起,我不明白你有什么问题。如果你可以写一个套接字,那么为什么阅读会成为一个问题呢?对我来说看起来很基本。之后......你有什么问题从json中提取这三个参数的值? – greenapps

+0

不明白你为什么不能从socket对象读取数据。服务器发送一个json文本。这只是文字。你可以阅读它。您的客户只需从输入流中读取文本。 – greenapps

+0

但无论如何它是一个坏主意,使用base64和json来传输文件。要传输的字节数量至少增加30%。 – greenapps

回答

0

我知道这个问题可能有不止一个答案,但仍然发布答案是一个好主意。 所以,我发现这个链接A Simple Java TCP Server and TCP Client帮助我开始使用我的解决方案。 我也使用Gson来解析我的JSON字符串,使用这个不错的教程:Android JSON Parsing with Gson Tutorial。 最后,我的代码看起来是这样的:

ServerSockerThread.java - 这是监听服务器的Java类,它等待传入的文件:

import java.io.IOException; 
import java.net.ServerSocket; 
import java.net.Socket; 

public class ServerSocketThread extends Thread { 
    static final int SocketServerPORT = 6789; 
    ServerSocket serverSocket; 

    @Override 
    public void run() { 
     Socket socket = null; 
     try { 
      serverSocket = new ServerSocket(SocketServerPORT); 
      while (true) { 
       socket = serverSocket.accept(); 
       new FileSaveThread().execute(socket); 
      } 
     } 
     catch (IOException e) { } 
     finally { 
      if (socket != null) { 
       try { 
        socket.close(); 
       } catch (IOException e) { } 
      } 
     } 
    } 

    protected void onDestroy() { 
     if (serverSocket != null) { 
      try { 
       serverSocket.close(); 
      } 
      catch (IOException e) { } 
     } 
    } 
} 

FileSaveThread.java - 这是java类正被上面的服务器类调用每个传入文件:

import android.os.AsyncTask; 
import android.os.Environment; 
import android.util.Base64; 
import com.google.gson.Gson; 
import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.Reader; 
import java.net.Socket; 

public class FileSaveThread extends AsyncTask<Socket, Void, DataRecord> { 

    @Override 
    protected void onPostExecute(DataRecord dataRecord) { 
     super.onPostExecute(dataRecord);   
    } 

    @Override 
    protected DataRecord doInBackground(Socket... sockets) { 
     DataRecord dataRecord = null; 

     if (isExternalStorageWritable() && sockets.length > 0) { 
      Socket socket = sockets[0]; 
      try { 
       Gson gson = new Gson(); 
       Reader reader = new InputStreamReader(socket.getInputStream()); 
       SocketObject socketObject = gson.fromJson(reader, SocketObject.class);    

       SaveFileToSDCard(socketObject.Image1, "Image1.png"); 
       SaveFileToSDCard(socketObject.Image2, "Image2.png"); 
       SaveFileToSDCard(socketObject.Image3, "Image3.png"); 

       dataRecord = new DataRecord(socketObject.Name); 
      } 
      catch (Exception e) { } 
      finally { 
       try { 
        socket.close(); 
       } catch (IOException e) { } 
      } 
     } 
     return dataRecord; 
    } 

    public boolean isExternalStorageWritable() { 
     String state = Environment.getExternalStorageState(); 
     if (Environment.MEDIA_MOUNTED.equals(state)) { 
      return true; 
     } 
     return false; 
    } 

    private void SaveFileToSDCard(String base64String, String fileName) throws IOException { 
     byte[] decodedString = Base64.decode(base64String.getBytes(), android.util.Base64.DEFAULT); 
     File file = new File(Environment.getExternalStorageDirectory(), fileName); 
     FileOutputStream fileOutputStream = new FileOutputStream(file, false); 
     fileOutputStream.write(decodedString); 
     fileOutputStream.close(); 
     fileOutputStream.flush(); 
    } 
} 
相关问题