【问题标题】:How To create the packet and send using java?如何使用java创建数据包并发送?
【发布时间】:2014-06-09 09:15:25
【问题描述】:

您好,我正在从 GPS 设备获取数据,我想通过创建数据包将响应发送回 Gps 设备我的数据包是这样的。

No. Field   TYPE    Length  description
1   sMark    Char   6   Flag of message (\r\n*KW\0)
2   packetLe short  2   Message Length
3   CMD  Short  2   0x8200
4   cErrorCodeChar  1   0x00OK, 0x01invalid deviceID
5   sEnd     Char   2   message end "\r\n"

我想要这样的 Crete Packet 使用此代码。

InetAddress IPAddress = receivePacket.getAddress();
              String sendString = "polo";
              sendData = sendString.getBytes();
              DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
              serverSocket.send(sendPacket);

我正在尝试这样。

 ByteArrayOutputStream bytearrypacket = new ByteArrayOutputStream();
        DataOutputStream dateoutputpacket = new DataOutputStream(bytearrypacket);
        dateoutputpacket.writeChars("\r\n*KW\0");
        dateoutputpacket.writeShort(15);
        dateoutputpacket.writeShort(82);
        dateoutputpacket.writeChar('1');
        dateoutputpacket.writeChars("\r\n");
        dateoutputpacket.flush();

        byte[] result = bytearrypacket.toByteArray();

更新:

   ByteArrayOutputStream bytearrypacket = new ByteArrayOutputStream();
    DataOutputStream dateoutputpacket = new DataOutputStream(bytearrypacket);
    dateoutputpacket.writeBytes("\r\n*KW\0");
    dateoutputpacket.writeShort(15);
    dateoutputpacket.writeShort(82);
    dateoutputpacket.writeByte(1);
    dateoutputpacket.writeBytes("\r\n");
    dateoutputpacket.flush();
    byte[] result = bytearrypacket.toByteArray();

更新 2:

try {
                        ByteArrayOutputStream bytearrypacket = new ByteArrayOutputStream();
                        DataOutputStream dateoutputpacket = new DataOutputStream(bytearrypacket);
                        dateoutputpacket.writeBytes("\r\n*KW\0");
                        dateoutputpacket.writeShort(15);
                        dateoutputpacket.writeShort(82);
                        dateoutputpacket.writeByte(1);
                        dateoutputpacket.writeBytes("\r\n");
                        dateoutputpacket.flush();
                        byte[] result = bytearrypacket.toByteArray();
                        DatagramPacket responsepacket = new DatagramPacket(result, result.length, packet.getAddress(), packet.getPort());
                        dsocket.send(responsepacket);
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    } catch (SecurityException se) {
                        se.printStackTrace();
                    } catch (IllegalBlockingModeException il) {
                        il.printStackTrace();
                    } catch (IllegalArgumentException ilg) {
                        ilg.printStackTrace();
                    }

【问题讨论】:

  • 这听起来像是一个显而易见的问题,但由于这是一个自定义数据包,长度字段是位还是字节?我在猜测字节,但值得澄清
  • 长度字段是字节数。
  • 我要生成的数据包总长度是13字节长

标签: java sockets packet


【解决方案1】:

我很快就把它放在一起了。使用此函数,您可以创建一个字节数组,其中包含正确位置的所有数据包信息。我使用了问题中的一些示例信息。这应该足以通过连接发送信息。您可以将字节数组直接传递到您的数据报中

public class Sample {

public static void main(String[] args){

    byte[] packet = createMsg("\r\n*KW\0", (short)15, (short)82, '1', "\r\n");

    for(byte b : packet){
        System.out.println(b);
    }

}
public static byte[] createMsg(String sMark, short packetle, short cmd, char cErrorCode, String sEnd){
    byte[] buffer = new byte[13];

    char[] sMarkArr = sMark.toCharArray();
    char[] sEndArr = sEnd.toCharArray();

    // sMark
    buffer[0] = (byte) sMarkArr[0];
    buffer[1] = (byte) sMarkArr[1];
    buffer[2] = (byte) sMarkArr[2];
    buffer[3] = (byte) sMarkArr[3];
    buffer[4] = (byte) sMarkArr[4];
    buffer[5] = (byte) sMarkArr[5];

    // packetle
    buffer[6] = (byte)(packetle & 0xFF);
    buffer[7] = (byte)((packetle >> 8) & 0xFF);

    // cmd
    buffer[8] = (byte)(cmd & 0xFF);
    buffer[9] = (byte)((cmd >> 8) & 0xFF);

    // cErrorCode
    buffer[10] = (byte)(cErrorCode);

    // sEnd
    buffer[11] = (byte)sEndArr[0];
    buffer[12] = (byte)sEndArr[1];

    return buffer;
}

}

请记住,在 java 中进行通信时,数据类型的大小和格式并不总是与其他一些语言相同。 查看http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html 以获取每种尺寸

希望对你有帮助

编辑:

数据包是 13 * 8 = 104 位 = 000000000000000000000000000000000000...

调用 buffer[0] = (byte)sMark 添加字符(例如 A)

数据包为 13 * 8 = 104 位 = 001000001000000000000000000000000000...

调用 buffer[6] = (byte)packetle 添加字符(例如 2)

数据包是 13 * 8 = 104 位 =

[字符6字节][短1字节]

[010000010000000000000000000000000000000000000000][00000010]...

注意:当您使用字节作为字符时,您需要添加一个额外的字节,因为 java 字符是 16 位的,否则您可能会丢失数据

【讨论】:

  • 这里你把前6个字节变成了一个字节写?如何把它变成 6byte
  • 缓冲区[1,2,3,4,5,7,9,12]呢?
  • Java char 原语只有 1 个字节长,但是数据包将是 000
  • 您已经错过了 OP 格式定义的一半以上的数据包数据。 -1
  • 请解释一下如何写。
【解决方案2】:

围绕 ByteArrayOutputStream 创建一个 DataOutputStream;使用其各种方法写入数据;然后从 ByteArrayOutputStream 中获取字节并在其周围包装一个 DatagramPacket。

【讨论】:

  • 我已经看到了你的答案,我也在尝试,请给我一些简短的例子。
  • 我建议您查找 Javadoc 中的 DataOutputStream。这很清楚。我希望任何专业程序员都能够从这个答案中陈述的内容着手。
  • 我不明白如何创建这种类型的数据包,请解释一下。
  • 我的回答中具体部分你不明白吗?
  • 在我的问题中,我有像 (\r\n*KW\0) 这样的字符,我需要采取单独的单独或完整的汽车阵列
猜你喜欢
  • 1970-01-01
  • 2019-01-29
  • 2016-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-12
相关资源
最近更新 更多