Android - 如何通过套接字处理复杂对象

时间:2017-02-12 15:50:42

标签: java android json sockets

我是Android的新手,我有一项任务是打开TCP套接字并侦听特定端口。 客户端应用程序应该向我发送2个图像和一个彼此相关的字符串,因此我们考虑将所有数据放在json对象中并发送此对象,而不是单独发送每个数据。 我的问题是,如何将这个json解析为保存2个图像和一个字符串? 所以这个json应该是这样的:

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。

1 个答案:

答案 0 :(得分: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();
    }
}