In general, there are two devices.
One sends the packets, and the other, respectively, receives them, changes them, and then sends them to the network.

And here the bottom line is that you need to leave the packet headers, ending, and replace the contents with another.

That is what happens: I need to raise the server, get the package, remove the contents from it and insert my own. Send package further. Even the scheme is:

Here - N is the number of "D".

alt text

I do not understand where to start, because I come across this for the first time. And I would like to understand what is painted on the picture.

    2 answers 2

    There seems to be nothing complicated. The picture shows the structure of 2 packages:

    1. The message that comes to you.
    2. The message you must send.

    For each message, the byte ordering structure (B1, B2, etc.) is described in detail, it also shows which part and where to transfer. The body of the original message consists of an array of data structure "D", each element of 6 bytes.

    But I have listed some common truths)), which you yourself probably understood)

    But what I do not understand about this picture:

    First, the "Measuring message is 98 bytes maximum" - therefore, the packet is of unfixed length, and how do we know about the end of the packet? + Not enough 10 bytes in the description, a maximum of 98, and the picture is painted only 88 bytes. Maybe there is some information?

    Secondly, the body of the original message in the picture is 84 bytes, but it needs to be placed in 103 bytes, are any manipulations performed with it? Or do you need to finish with zeros to a certain length?

    ===============================================

    Still have questions) here are a look at an approximate algorithm

    1. On your server (in Figure 2, device 2), we read the stream of bytes, first we take the first byte and check the header, judging by the picture, the header is always 23, if yes, we continue to read, if not, we need more information about other packages and further actions

    2. Now that we understand what a packet is, we need to know the rest of the data; to do this, we need to understand the packet length, and here again it is not clear how to calculate it is always fixed and equal to 113 bytes (then you need to read 110 more bytes + crc (2 bytes) ), or "N" is the number of D, as @avp said, then you need to count another byte, we will assume that this is a count, then the formula will be such a count * 6 + crc (2 bytes)

    3. When you receive the message body, you need to verify crc (last 2 bytes), but it is not written here for which part of the message to verify it?

    4. If crc coincided, now you can create a new package, but how to form it is also not entirely clear

    • 2
      In fact, there is clearly not enough information for an exact solution (one can only guess). - is the stream of bytes on a tcp connection the only described packets? - Byte B2 (denoted by N) is the number D (6 bytes each) in a packet or the number of bytes (and which ones)? - for which bytes to count CRC (do B1 and B2 turn on)? - what is the meaning of B1 (heading? always? equal to 023?) ??? - if the calculated CRC does not match the CRC in the packet, then what should I send next? (it is clear that when inserting your CRC data you need to recalculate) - avp
    • Thanks for the answer! In general, on neponyatkam: in the first measurement message, not 98 bytes, but 88 bytes maximum, and in the second also not 123, but 113 bytes. Secondly, the second picture in the original was almost the same, I just didn’t know how to cut and how not. ! [text] [1] [1]: upyourpic.org/images/201405/j1ly1at9hv.png - lampa
    • He described his answer in more detail, but so far there are many incomprehensible moments. - Lookingfor
    • @Lookingfor, thanks. I now looked at the pictures again, more meaningfully, and I understand that I indicated incorrectly. The first message must be completely inserted into the second. Well, it turns out that in the second message, blocks 24 through 111 are just 88 bytes long. Requested information. N is the number "D". - lampa
    • @Lookingfor, did everything, thanks for the hint with the types. - lampa

    In short, this is what I managed to set up:

    Here is device 1:

    import java.io.*; import java.net.*; import java.util.*; import java.nio.ByteBuffer; import java.math.BigInteger; class TCPClient { public static void main(String argv[]) throws Exception { Random rand = new Random(); int[] keys = {20, 1480, 70, 1520, 1470, 60, 0, -16, -15, -14}; float[] values = {0.000f, 0.000f, 0.000f, 0.000f, 0.006f, 0.000f, 0f, 22.150f, 744.301f, 41.136f}; byte[] bots = new byte[88]; byte[] one_byte = new byte[4]; //one_byte = intToByteArray(023, 1); bots[0] = intToByteArray(23, 1)[0]; bots[1] = intToByteArray(14, 1)[0]; for(int i=2, key_store = 0; i < 81; i++, key_store++) { one_byte = intToByteArray(keys[key_store], 2); // код ЗХВ bots[i++] = one_byte[0]; bots[i++] = one_byte[1]; one_byte = FloatToByteArray(values[key_store]); // отчет float bots[i++] = one_byte[0]; bots[i++] = one_byte[1]; bots[i++] = one_byte[2]; bots[i++] = one_byte[3]; } one_byte = intToByteArray(rand.nextInt(), 2); // код CRC 16 bots[86] = one_byte[0]; bots[87] = one_byte[1]; for(int i=0; i < 88; i++) { System.out.print(bots[i] + " "); } Socket socket = new Socket("localhost", 6789); DataOutputStream outToServer = new DataOutputStream(socket.getOutputStream()); BufferedReader inFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream())); outToServer.write(bots); int bytesWritten = outToServer.size(); System.out.println("Total " + bytesWritten + " bytes are written to stream."); String modifiedSentence = inFromServer.readLine(); System.out.println("FROM SERVER: " + modifiedSentence); socket.close(); } public static byte[] FloatToByteArray(float value) { int bits = Float.floatToIntBits(value); byte[] bytes = new byte[4]; bytes[0] = (byte)(bits & 0xff); bytes[1] = (byte)((bits >> 8) & 0xff); bytes[2] = (byte)((bits >> 16) & 0xff); bytes[3] = (byte)((bits >> 24) & 0xff); return bytes; } public static byte[] intToByteArray(int value, int length) { if(length == 2) { byte[] data = new byte[2]; data[0] = (byte) (value & 0xFF); data[1] = (byte) ((value >> 8) & 0xFF); return data; } else { BigInteger bigInt = BigInteger.valueOf(value); return bigInt.toByteArray(); } } static int crc16(final byte[] buffer) { int crc = 0xFFFF; for (int j = 0; j < buffer.length ; j++) { crc = ((crc >>> 8) | (crc << 8) )& 0xffff; crc ^= (buffer[j] & 0xff);//byte to int, trunc sign crc ^= ((crc & 0xff) >> 4); crc ^= (crc << 12) & 0xffff; crc ^= ((crc & 0xFF) << 5) & 0xffff; } crc &= 0xffff; return crc; } } 

    How I think how it works: the first 2 bytes - I encode an int in byte and write it down. Next come the "D" structures containing 6 bytes each, where the first 2 bytes are the key and the remaining 4 are the value.

    Well, at the end of the CRC code.

    But what happens is that on device 2 I accept the request like this:

     Socket connectionSocket = welcomeSocket.accept(); BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream())); DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream()); while ((i = inFromClient.read()) != -1) { } 

    and I get an int value, when byte should come, I sent it to byte . What to do? Generally correct?

    • Oh, it worked like this: Socket connectionSocket = welcomeSocket.accept (); DataInputStream inFromClient = new DataInputStream (connectionSocket.getInputStream ()); DataOutputStream outToClient = new DataOutputStream (connectionSocket.getOutputStream ()); while (inFromClient.available ()> 0) {byte b = inFromClient.readByte (); System.out.print (b + ""); } - lampa
    • Now I can not recover the message from the bytes. And anyway, why do I have bytes with negative signs? >> 23 14 20 0 0 0 0 0 -56 5 0 0 0 0 70 0 0 0 0 0 -16 5 0 0 0 0 -66 5 -90 -101 -60 59 60 0 0 0 0 0 0 0 0 0 0 0 -16 -1 51 51 -79 65 -15 -1 68 19 58 68 -14 -1 68 -117 36 66 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -54 76 - lampa
    • There is such a class, ByteBuffer is called, do everything with his help, make your life a little easier :) - Lookingfor
    • @Lookingfor, if everything is clear with the float, it takes 4 bytes, then it’s not clear with int values ​​that should take 1 or 2 bytes, ByteBuffer does not allow this. How to get out? I myself tried to fix it in hours 3: D - lampa
    • I didn’t quite understand what "int values ​​mean that should take 1 or 2 bytes", int - always 4 bytes, besides int, there are such primitives as byte (1 byte, also note that the range of values ​​is from -128 to 127) and short (2 bytes), in ByteBuffer for writing / reading there are methods get / put and getShort / putShort. - Lookingfor