简体   繁体   中英

Sending and receiving several JSON files with java sockets

I am making an android application that should send and receive some json files through a wifi direct connection (whenever another device is connected, they both trade all their json files). This question is mostly about what would be the best practice, since I am fairly new both to android and java. When a wifi direct connection is established one of the two devices (the group owner) becomes the server and opens a server socket; the other connects to said socket and sends one single json file to the server.

I want the client to send all his json files and then receive all the json files from the server, and I'm wondering how it should be done: how do I tell one file is over? Should I send the lenght of the file ahead, or make the client wait for an acknowledgement for when the server is done reading? Can I signal "End of Data" (by closing the OutputStream?) to stop the reading loop on the receiving end and then start sending another file?

To have some context, this is currently the code I'm using:

Client side

@Override
    protected String doInBackground(Void... params) {
        Socket socket = new Socket();
        try {
            Log.d(TAG, "Opening client socket - ");
            socket.bind(null);
            socket.connect((new InetSocketAddress(mHost, Constants.PORT)), SOCKET_TIMEOUT);

            Log.d(TAG, "Client socket - " + socket.isConnected());
            OutputStream stream = socket.getOutputStream();

            //There is only one file, so the loop here runs only once
            File dir = Utils.graffitiDir(context);
            for (File tmp : dir.listFiles()) {
                FileInputStream in = new FileInputStream(tmp);
                Utils.copyFileInOut(in, stream);
            }
            Log.d(TAG, "Client: Data written");
            return "ok";
        } catch (IOException e) {
            Log.e(TAG, e.getMessage());
            return null;
        }
        finally {
            if (socket != null) {
                if (socket.isConnected()) {
                    try {
                        socket.close();
                    } catch (IOException e) {
                        // Give up
                        e.printStackTrace();
                    }
                }
            }
        }
    }

Server side

@Override
    protected String doInBackground(Void... params) {
        try {
            ServerSocket serverSocket = new ServerSocket(Constants.PORT);
            byte buf[] = new byte[4];
            String res;
            Log.d(TAG, "Server: Socket opened");
            Socket client = serverSocket.accept();
            Log.d(TAG, "Server: connection done");

            File f = new File(context.getFilesDir(), Constants.DIRECTORY);
            File dirs = new File(f.getParent());
            if (!dirs.exists())
                dirs.mkdirs();
            f.createNewFile();
            File newf = new File(f, Calendar.getInstance().getTime().toString());
            Log.d(TAG, "server: copying files " + f.toString());
            InputStream inputstream = client.getInputStream();
            //copyFile(inputstream);
            Utils.copyFileInOut(inputstream, new FileOutputStream(newf));
            serverSocket.close();
            return newf.getAbsolutePath();
        } catch (IOException e) {
            Log.e(TAG, e.getMessage());
            return null;
        }
    }

The copyFileInOut function:

public static boolean copyFileInOut(InputStream inputStream, OutputStream out) {
    byte buf[] = new byte[1024];
    int len;
    long startTime=System.currentTimeMillis();

    try {
        while ((len = inputStream.read(buf)) != -1) {
            out.write(buf, 0, len);
            Log.d("copyfile", "I'm writing");
        }
        out.close();
        inputStream.close();
        long endTime=System.currentTimeMillis()-startTime;
        Log.d("copyfile", "Time taken to transfer all bytes is : " + endTime);

    } catch (IOException e) {
        Log.d(TAG, e.toString());
        return false;
    }
    return true;
}

As a sidenote, I've seen a couple of similar questions ( Sending and receiving files on socket ) where the answer suggested to send the length of the file ahead, but I feel like my situation is a bit different, and I don't have the necessary experience to find out what is the best solution. I apologize if this is an obvious question, but I couldn't find an answer by myself.

In your case you should

1. send the number of files you are going to send first,
2. then send length of a file and that file. repeat for all files.

after this the server can also use the same order of sending number of files, the size of a file, that file repeat for all files.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM