Java – how to send packets using binary communication protocol on TCP port

I am developing a device that can measure some readings through sensors. The device is operated by Android applications. I must read data from the TCP layer. This is the code that sends data on 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);
}

}

The packet format contains the boundary between data packets when communicating with the device on TCP. In this case, if the packet order is incorrect or any data packets are lost, you can use "header start" to identify the new packet. Therefore, the first two bytes in the packet represent the beginning of the packet

Header start: a two byte field indicating the start of each packet. 0x55aa is a two byte number used as the header start

Protocol version: a one byte field used to specify the version of the protocol used. The version specified in the payload will determine the structure of the payload. At any given time, the device will support a single protocol version. The current protocol version is "1"

DSN: the serial number is a 1-byte field, which will uniquely identify the packet. The requester of the packet will have to fill this field in the request payload; Responders must populate the response payload with the same unique identifier

Request ID: a one byte field specifies the command ID. the payload will be parsed based on the command ID. in the case of requesting the payload, this field will be non-zero; In the case of a response, the field will be zero

Payload length: the two byte field specifies the length of the payload (in bytes). It specifies the number of bytes after the payload length field. The payload length does not include the header length and CRC. Currently, the maximum payload length supported by the gateway device is 512 (bytes). CRC: a 1-byte field, It will be calculated by XOR operation on all bytes and adding XOR count 0

It is working. But according to the document, I must send packets using binary communication protocol, including header start, payload data, etc. How to send these parameters in packet structure? How to create a packet?

Any help is appreciated

resolvent:

The main mistake is that I don't consider the size of too many raw data types

Bytes = 1 byte

Short = 2 bytes

Int = 4 bytes

Length = 8 bytes

Floating point number = 4 bytes

Double = 8 bytes

Character = 2 bytes

After referencing the size of the original data type, I realized that we should track the packet size and index because we are dealing with byte arrays

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;

}



}

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>