Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从套接字读取JSON数据而不是一行?_Java_Android_Json_Sockets_Tcp - Fatal编程技术网

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

Java 如何从套接字读取JSON数据而不是一行?,java,android,json,sockets,tcp,Java,Android,Json,Sockets,Tcp,我的应用程序通过WiFi直接连接到传感器。然后,它连接到一个套接字,并应该读取数据。数据是JSON,看起来像{“d”:{temp_mC;33416,“湿度_ppm”…更多数据…}。传感器每2分钟发送一次数据。以前我只能读取服务器发送的行,但由于传感器不发送行,我需要重做我的TCPClient类。我认为我可以实现这段代码 ByteArrayOutputStream result = new ByteArrayOutputStream(); byte[] buffer = new byte[1024

我的应用程序通过WiFi直接连接到传感器。然后,它连接到一个套接字,并应该读取数据。数据是JSON,看起来像{“d”:{temp_mC;33416,“湿度_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数据并将其转换为字符串,以便以后可以解析它吗

TCP客户

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);
}

}
我的班级在其他活动中

  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....

    }

}
公共类ConnectTask扩展了异步任务{
@凌驾
受保护的TcpClient doInBackground(字符串…消息){
//我们创建一个TCPClient对象
mTcpClient=新的TcpClient(新的TcpClient.OnMessageReceived(){
@凌驾
//这里实现了messageReceived方法
已接收公共无效消息(字符串消息){
//此方法调用onProgressUpdate
出版进度(信息);
}
});
mTcpClient.run();
返回null;
}
@凌驾
受保护的void onProgressUpdate(字符串…值){
super.onProgressUpdate(值);
CO2=数值[0];
//从服务器收到的响应
Log.d(“CO2”,数值[0]);
//在此处处理服务器响应。。。。
}
}

处理这种情况的正确方法是立即发送整个数据

这可以通过以下方式首先发送数据大小,然后发送数据内容:

outputStream.writeInt(message.length); 
outputStream.write(message);
int len = socketDataInputStream.readInt();                    
byte[] message = new byte[len];
socketDataInputStream.readFully(message, 0, message.length);
阅读消息时,解析长度,然后像这样阅读整个消息:

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

希望这有帮助,祝好运。

当您说“发送数据大小”时“,你是说从传感器上?因为我无法对传感器进行编程。对不起,我理解错了。如果数据是从一个没有换行符的服务器发送的,这是正常的,你有经验吗?我应该联系制造传感器的公司吗?或者有没有一个解决方案来读取数据,并将每个新数据放在一个单独的字符串中?似乎我误解了您的意思,您是否只需要将JSON消息转换为字符串并在以后解析它?“com.google.code.gson”可以轻松做到这一点。将其作为“compile'com.google.code.gson:gson:2.8.0”包含在你的应用程序gradle中。如果从服务器发送的数据结束时没有换行符,那是因为发送者没有在每次发送后关闭套接字。一个解决办法是检查发送的数据是否小于缓冲区,然后将其视为消息的结尾。