如何从套接字读取JSON数据而不是行?

时间:2017-04-10 14:04:45

标签: java android json sockets tcp

我的应用程序通过WiFi直接连接到传感器。然后它连接到套接字并且应该读取数据。数据是JSON,看起来像{" d":{temp_mC&#34 ;; 33416," humidity_ppm" ...更多数据....}}。传感器每2分钟发送一次数据。之前我只能读取服务器发送的行,但由于传感器没有发送行,我需要重做我的TCPClient类。我想我可以实现这个代码。

ByteArrayOutputStream result = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = socket.getInputStream().read(buffer)) != -1) {
result.write(buffer, 0, length);
}
// StandardCharsets.UTF_8.name() > JDK 7
return result.toString("UTF-8");

要将JSON数据转换为字符串,我必须解析它,但这是为了以后。

我的旧代码看起来像这样,有没有人知道如何重新制作我的旧代码来实现上面的方法或类似的方法所以我可以读取JSON数据并将其转换为字符串,以便我以后可以解析它?

TcpClient的

public class TcpClient {

....

/**
 * Constructor of the class. OnMessagedReceived listens for the messages received from server
 */
public TcpClient(OnMessageReceived listener) {
    mMessageListener = listener;

}

/**
 * Sends the message entered by client to the server
 *
 * @param message text entered by client
 */

/**
 * Close the connection and release the members
 */
public void stopClient() {

    mRun = false;

    mMessageListener = null;
    mBufferIn = null;
    mServerMessage = null;
}

public void run() {

    mRun = true;

    try {
        //here you must put your computer's IP address.
        InetAddress serverAddr = InetAddress.getByName(SERVER_IP);

        Log.e("TCP Client", "C: Connecting...");

        //create a socket to make the connection with the server
        Socket socket = new Socket(serverAddr, SERVER_PORT);

        try {


            //receives the message which the server sends back
            mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));


            //in this while the client listens for the messages sent by the server
            while (mRun) {

                mServerMessage = mBufferIn.readLine();

                if (mServerMessage != null && mMessageListener != null) {
                    //call the method messageReceived from MyActivity class
                    mMessageListener.messageReceived(mServerMessage);
                }

            }

            Log.e("RESPONSE FROM SERVER", "S: Received Message: '" + mServerMessage + "'");

        } catch (Exception e) {

            Log.e("TCP", "S: Error", e);

        } finally {
            //the socket must be closed. It is not possible to reconnect to this socket
            // after it is closed, which means a new socket instance has to be created.
            socket.close();
        }

    } catch (Exception e) {

        Log.e("TCP", "C: Error", e);

    }

}

//Declare the interface. The method messageReceived(String message) will must be implemented in the MyActivity
//class at on asynckTask doInBackground
public interface OnMessageReceived {
    public void messageReceived(String message);
}

}

其他活动中的我的AsyncClass

  public class ConnectTask extends AsyncTask<String, String, TcpClient> {

    @Override
    protected TcpClient doInBackground(String... message) {

        //we create a TCPClient object
        mTcpClient = new TcpClient(new TcpClient.OnMessageReceived() {
            @Override
            //here the messageReceived method is implemented
            public void messageReceived(String message) {
                //this method calls the onProgressUpdate
                publishProgress(message);
            }
        });
        mTcpClient.run();

        return null;
    }

    @Override
    protected void onProgressUpdate(String... values) {
        super.onProgressUpdate(values);
        CO2 = values[0];
        //response received from server
        Log.d("CO2", values[0]);
        //process server response here....

    }

}

1 个答案:

答案 0 :(得分:0)

处理此类案件的正确方法是立即发送整个数据。

首先发送数据大小,然后发送数据内容,如下所示:

outputStream.writeInt(message.length); 
outputStream.write(message);

并且在阅读消息时,解析长度,然后读取整个消息:

int len = socketDataInputStream.readInt();                    
byte[] message = new byte[len];
socketDataInputStream.readFully(message, 0, message.length);

希望这有帮助,祝你好运。