【发布时间】:2022-04-11 17:03:19
【问题描述】:
我正在开发一种可以通过传感器测量一些读数的设备。设备由 Android 应用程序操作。我必须从 TCP 层读取数据。这是在 TCP 上发送数据的代码
TcpClient.java
import android.util.Log;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
/**
* Created by shahbaz on 25/4/17.
*/
public class TcpClient {
public static final String SERVER_IP = "192.168.1.76"; //server IP address
public static final int SERVER_PORT = 1800;
// message to send to the server
private String mServerMessage;
// sends message received notifications
private OnMessageReceived mMessageListener = null;
// while this is true, the server will continue running
private boolean mRun = false;
// used to send messages
private PrintWriter mBufferOut;
// used to read messages from the server
private BufferedReader mBufferIn;
/**
* 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
*/
public void sendMessage(String message) {
if (mBufferOut != null && !mBufferOut.checkError()) {
mBufferOut.println(message);
mBufferOut.flush();
}
}
/**
* Close the connection and release the members
*/
public void stopClient() {
mRun = false;
if (mBufferOut != null) {
mBufferOut.flush();
mBufferOut.close();
}
mMessageListener = null;
mBufferIn = null;
mBufferOut = 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 {
//sends the message to the server
mBufferOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
//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);
}
}
数据包格式包含, 在 TCP 上与设备通信时,不会识别数据包之间的边界,在这种情况下,如果数据包乱序或任何数据包丢失,则可以使用“标头开始”识别新数据包。 因此,数据包中的前 2 个字节表示数据包的开始。
Header start:两字节字段,指示每个数据包的开始。 0x55AA 是一个 2 字节的数字,用作标头开始。
协议版本:一字节字段,用于指定正在使用的协议版本。有效载荷中指定的版本将决定有效载荷结构。在任何给定时刻,设备都将支持单一协议版本。当前协议版本为“1”。
DSN:序列号是 1 字节的字段,用于唯一标识数据包。数据包的请求者必须在请求有效负载中填写此字段;响应者必须在响应负载中填写相同的唯一标识符。
Request Id:单字节字段指定命令ID。有效载荷的解析将根据命令 id 完成。在请求负载的情况下,该字段将非零,在响应的情况下,它将为零。
有效负载长度:两字节字段指定有效负载的长度(以字节为单位)。它指定有效载荷长度字段后面的字节数。在有效载荷长度中,不包括报头长度和CRC。目前,网关设备支持的最大有效载荷长度为 512(字节)。 CRC:1字节字段,将通过对所有字节进行异或并加上0的异或计数来计算。
而且它正在工作。但根据文档,我必须使用二进制通信协议发送数据包。包括header start、payload data等。这些params如何以packet结构发送?如何创建数据包?
感谢任何帮助。
【问题讨论】:
-
无法分享该文档。只是想知道如何发送这些参数
-
由于您正在处理发送字节,您将(可能)想要使用
DataInputStream和DataOutputStream。我会使用长度为7的一个字节数组来存储Header Start到Payload Length。然后另一个字节数组,最大长度为(2^15),用于存储Payload Data和CRC。然后,我将两个数组连接成一个大小为7 + (2^15)的字节数组,并使用DataOutputStream#write(byte[] array, int offset, int length)写入该数组,其中offset将是0,length将是7 + (2^15)。然而,这是一种非常低级的方法。 -
您能否用一些代码发布答案。那么有效载荷数据呢。它的结构是什么
-
我会,但我上班迟到了。感谢您编辑您的问题,由于您的编辑,我将您的问题的反对票改为赞成票,因为我有兴趣看到这个问题的一些答案。下班后我会检查一下,看看是否发布了任何答案,如果没有,我会尝试制定一个。
-
谢谢乔尼。请稍后在您有空时发布您的答案。我也会试试的。
标签: java android sockets tcp tcpclient