我正在开发一种可以通过传感器测量一些读数的设备.设备由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个字节代表数据包的开始.
标头开始:两字节字段,指示每个数据包的开始. 0x55AA是2个字节的数字,用作标头开始.
协议版本:一字节字段,用于指定所使用协议的版本.有效负载中指定的版本将决定有效负载的结构.在任何给定的时刻,设备将支持单个协议版本.当前协议版本为“ 1”.
DSN:序列号是1个字节的字段,它将唯一地标识数据包.数据包的请求者将不得不在请求有效负载中填充此字段;响应者必须在响应有效负载中填充相同的唯一标识符.
请求ID:一字节字段指定命令ID.有效载荷的解析将基于命令ID进行.在请求有效负载的情况下,该字段将为非零;在响应的情况下,该字段将为零.
有效负载长度:两字节字段指定有效负载的长度(以字节为单位).它指定有效负载长度字段后面的字节数.在有效载荷长度中,不包括报头长度和CRC.当前,网关设备支持的最大有效负载长度为512(字节).
CRC:1个字节的字段,将通过对所有字节进行XOR运算并加上XOR计数0来计算.
它正在工作.但是根据文档,我必须使用二进制通信协议发送数据包.包括标头开始,有效载荷数据等.如何以包结构发送这些参数?如何创建数据包?
任何帮助表示赞赏.
解决方法:
主要的错误是我没有考虑太多原始数据类型的大小.
位元组= 1个位元组
短= 2字节
int = 4个字节
长= 8字节
浮点数= 4字节
双倍= 8字节
字符= 2字节
引用原始数据类型的大小后,我意识到我们应该跟踪数据包的大小和索引,因为我们正在处理字节数组.
TcpPacket.java
public class TcpPacket {private static int header_start = 0x55AA;private static int protocol_version = 1;private PacketUtils packetUtils = new PacketUtils(); public byte[] getHandshakePacket() { int request_ID = 1; byte[] header_data = packetUtils.ItoBA2(header_start); byte[] payload_data = packetUtils.ItoBA4(packetUtils.getDateTime()); byte[] payload_length = packetUtils.ItoBA2(4); byte[] a_data = new byte[]{header_data[0], header_data[1], (byte) protocol_version, packetUtils.getDSN(), (byte) request_ID, payload_length[0], payload_length[1], payload_data[0], payload_data[1], payload_data[2], payload_data[3]}; byte[] b_data = new byte[]{ packetUtils.getCRC(a_data)}; byte[] packet_data = packetUtils.concatBytes(a_data,b_data); return packet_data; }}
PacketUtils.java
public class PacketUtils {public byte[] ItoBA4(int value) { // integer to bytes function (return byte array of 4 bytes) return new byte[] { (byte)(value >>> 24), (byte)(value >>> 16), (byte)(value >>> 8), (byte)value};}public byte[] ItoBA2(int value) { // integer to bytes function (return byte array of 2 bytes) return new byte[] { (byte)(value >>> 8), (byte)value};}public byte getDSN() // return one byte random number{ char[] chars = "1234567890".tochararray(); StringBuilder sb = new StringBuilder(); Random random = new Random(); for (int i = 0; i < 1; i++) { char c = chars[random.nextInt(chars.length)]; sb.append(c); } byte output = Byte.valueOf(sb.toString()); return output;}public byte getCRC(byte[] packet) // required CRC function (return byte){ try { if (packet == null) { //Logger.Error("empty packet received"); return (byte)0; } byte XORCheckSum = 0; byte zeroCount = 0; byte FFCount = 0; for (int i = 0; i < packet.length; i++) { XORCheckSum ^= packet[i]; if (packet[i] == (byte) 0) { zeroCount++; continue; } if (packet[i] == (byte)255) { FFCount++; continue; } } XORCheckSum ^= zeroCount; XORCheckSum ^= FFCount; return XORCheckSum; } catch (Exception ex) { //Logger.Error(ex); return (byte)0; }}byte[] concatBytes(byte[]...arrays) // concatenate byte arrays{ // Determine the length of the result array int totalLength = 0; for (int i = 0; i < arrays.length; i++) { totalLength += arrays[i].length; } // create the result array byte[] result = new byte[totalLength]; // copy the source arrays into the result array int currentIndex = 0; for (int i = 0; i < arrays.length; i++) { System.arraycopy(arrays[i], 0, result, currentIndex, arrays[i].length); currentIndex += arrays[i].length; } return result;}public int getDateTime(){ int dateInSec = (int) (System.currentTimeMillis() / 1000); return dateInSec;}}
总结 以上是内存溢出为你收集整理的java-如何在tcp端口上使用二进制通信协议发送数据包全部内容,希望文章能够帮你解决java-如何在tcp端口上使用二进制通信协议发送数据包所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)