简体   繁体   English

使用Java套接字发送和接收多个JSON文件

[英]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). 我正在制作一个应该通过wifi直接连接发送和接收一些json文件的android应用程序(无论何时连接了另一台设备,它们都交换了所有的json文件)。 This question is mostly about what would be the best practice, since I am fairly new both to android and java. 这个问题主要是关于最佳实践,因为对于android和java来说我都是新手。 When a wifi direct connection is established one of the two devices (the group owner) becomes the server and opens a server socket; 建立wifi直接连接后,两个设备之一(组所有者)将成为服务器并打开服务器套接字。 the other connects to said socket and sends one single json file to the server. 另一个连接到所述套接字,并向服务器发送一个单个json文件。

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? 我希望客户端发送所有他的json文件,然后从服务器接收所有json文件,我想知道应该怎么做:如何告诉一个文件结束了? 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? 我可以发信号通知“数据结束”(通过关闭OutputStream吗?)以在接收端停止读取循环,然后开始发送另一个文件?

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: copyFileInOut函数:

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, 1.发送您要首先发送的文件数,
2. then send length of a file and that file. 2.然后发送一个文件和该文件的长度。 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. 在此之后,服务器还可以使用相同的顺序发送文件数量,文件大小,然后对所有文件重复该文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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