简体   繁体   English

Java SSL套接字通信-发送和接收

[英]Java SSL Socket Communication - Both Sending and Receiving

Consider the client send a message to the server, then the server replies to the client. 考虑客户端向服务器发送消息,然后服务器回复客户端。

Client code 客户代码

public void run() {
    try {
        SSLSocketfactory f = (SSLSocketFactory) SSLSocketFactory.getDefault();
        SSLSocket socket = (SSLSocket) f.createSocket(Common.JSON_SERVER_IP, Integer.parseInt(Common.JSON_SERVER_PORT));
        String[] suites = socket.getSupportedCipherSuites();
        socket.setEnabledCipherSuites(suites);

        Log.i("Socket", "Created");
        DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
        File f = new File(Common.PATH, Common.JSON_FILE_NAME);
        FileInputStream fis = new FileInputStream(f);

        byte sendBytes[] = new byte[1024];
        int fileSize = 0;
        int length = 0;

        // Data Send Start!
        while ((length = fis.read(sendBytes, 0, sendBytes.length)) > 0) {
            fileSize += length;
            dos.write(sendBytes, 0, length);
            dos.flush();
        }

        Log.i("Socket", "Data Send Finish");
        final int final_fileSize = fileSize;
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(activity.getApplicationContext(), "JSON File Size :" + final_fileSize + "Bytes", Toast.LENGTH_SHORT).show();
            }
        });

        Log.i("Socket", "Output Close");
        // Data Receive Start!
        InputStream is = socket.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));

        // receive the response from Server
        String reply = "";
        String str = "JSON";
        Log.i("Socket", "Receive Ready");
        /* Example result from Server 
        {
            "ret":[{"id":"COM_DATA_002","errCd":0, "errMsg":""}],
            "Value":[{"updateType":0, "fileURL":"http://127.0.0.1/filePath"}]
        }*/
        while ((reply = br.readLine()) != null) {
            Log.i("Socket", "Parsing");
            Object obj_p=JSONValue.parse(reply);
            JSONObject obj_j=(JSONObject)obj_p;
            Object target = obj_j.get("Value");
            JSONArray obj_value = (JSONArray)target;
            JSONObject url_val=(JSONObject)obj_value.get(0);
            String url = (String)url_val.get("fileURL");
            URL urlDB = new URL(url);
            URLConnection getDB = urlDB.openConnection();
            // Get New DB or query
        }
        Log.i("Socket", "File Get");
        if(str.length() != 0) {
            str = "[" + Common.getDateCurrentTimeZone(System.currentTimeMillis()) + "]\n" + str + "\n"; 
            Log.i(Common.TAG, str);
        }

        final String text = str;
        is.close();
        br.close();

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (dos != null)
            try {
                dos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        if (fis != null)
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        if (socket != null)
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    }
}

Server Code 服务器代码

public void run() {
    String fileName = "JSON.txt";

    try {
        // receive file
        receiveFile(fileName);

        // load receive file
        File file = new File(Common.defaultReceivedData, fileName);
        BufferedReader in = new BufferedReader(new FileReader(file));
        // String SendfileName = "ClientVersion.txt";
        String SendfileName = "Return.txt";
        File SendFile = new File(Common.defaultSendData, SendfileName);
        String s;
        Object obj;
        JSONObject obj2;
        String det;

        // File write and send...

        in.close();

    } catch (IOException e) {
        e.printStackTrace();
    }
}

public static void receiveFile(String fileName) throws IOException{

    int length = 0;
    int size = 0;

    DataInputStream dis = new DataInputStream(send.getInputStream());
    fileName = "JSON.txt";
    FileOutputStream fos = new FileOutputStream(new File(Common.defaultReceivedData, fileName));

    byte[] inputByte = new byte[1024];
    while ((length = dis.read(inputByte, 0, inputByte.length)) > 0) {
        System.out.println(length);
        size += length;
        fos.write(inputByte, 0, length);
        fos.flush();
    }
    fos.close();
    System.out.println("Received JSON data! [FileSize: " + size + "]");
}

When the client sends a message to the server, the communication stuck. 当客户端向服务器发送消息时,通信停止。

Client 客户

03-11 15:38:46.476: I/Socket(30160): Created
03-11 15:38:46.606: I/Socket(30160): Data Send Finish
03-11 15:38:46.606: I/Socket(30160): Output Close
03-11 15:38:46.616: I/Socket(30160): Receive Ready

Server 服务器

Client is connected: IP is xxx.xxx.xxx.xxx
57

In this code, the server completes receiving the message only after the client has stopped. 在此代码中,服务器仅在客户端停止后才完成接收消息。 What can be done in order to complete this communication normally? 为了正常完成此通信可以做什么?

The server is reading the file from the socket until end of stream. 服务器正在从套接字读取文件,直到流结束。

The client doesn't close the connection, instead it tries to read a response from the server, again until end of stream. 客户端不会关闭连接,而是尝试再次从服务器读取响应,直到流结束。

So neither peer has closed the connection, so end of stream never arrives, so both sides are blocked in read, so you have implemented a networked deadlock. 因此,两个对等方都没有关闭连接,因此流的末尾永不到达,因此双方都无法读取,因此您实现了网络死锁。

You need to send the length of the file ahead of the file, so that the server knows when to stop reading. 您需要在文件之前发送文件长度,以便服务器知道何时停止读取。

Or, if you're only going to send one file per connection, the client could shutdown the connection for output, which would give the server the EOS it is looking for, whereupon its read loop would terminate, it would send its reply, and then close the connection, which would give the client the EOS it is looking for, so it would fall out of its read loop and close the connection. 或者,如果您仅要为每个连接发送一个文件,则客户端可以关闭该连接以进行输出,这将向服务器提供其正在寻找的EOS,随后其读取循环将终止,它将发送答复,并且然后关闭连接,这将使客户寻找EOS,所以它会掉出读取循环和关闭连接。

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

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