在UDP传输之后,将字节编码的数据转换回INT32的问题



我正在使用我用来指示正在发送的数据类型的子标题来组装udp通信的数据报。客户端正在运行c#,服务器正在运行Java,并且子标题是单个INT32 SO 4字节的数据。

数据成功到达服务器,并正确解释了子标题 数据,但是当我使用bitConverter.toint.toint32(subheader,0(将响应发送给客户端时,将导致8位数字,该编号未映射对于我任何预期的整数。但是,发送的数据通过跳过子标题可以正确显示,这使我认为问题是子标记编码/解码过程的独有的。

i在两端都有可以从字节数组擦洗子标题的方法,并尝试将磨砂器的子标题映射到msgType。就像我提到的那样,一切都按照服务器上的预期工作,所以我怀疑问题在于在服务器上编码或向客户端解码。

我还尝试使用memorystream和binarleader转换为int32,但结果相同。

c#客户端:

        const SUBHEADER_SIZE = 4; // 4 bytes to an Int32
        private void ReceiveUdp(IAsyncResult packet)
        {
            IPEndPoint remote = (IPEndPoint)Udp.Client.RemoteEndPoint;
            byte[] received = Udp.EndReceive(packet, ref remote);
            MsgType type = GetMsgType(received);
            string msg;
            switch (type)
            {
                case MsgType.POS:
                case MsgType.STATE:
                case MsgType.STATUS:
                    msg = Encoding.ASCII.GetString(ScrubSubheader(received));
                    if (msg.Equals("0"))
                        Disconnect();
                    break;
                case MsgType.MSG:   // Default to MSG
                default:
                    msg = Encoding.ASCII.GetString(ScrubSubheader(received));
                    LocalConsole.Instance.Log("Received [" + type + "] " + msg + " from " + remote.Address + " on port " + remote.Port);
                    break;
            }
        }
        public static byte[] ScrubSubheader(byte[] arr)
        {
            byte[] scrubbed = new byte[arr.Length - SUBHEADER_SIZE];
            for (int i = 0; i < scrubbed.Length; i++)
                scrubbed[i] = arr[i + SUBHEADER_SIZE];
            return scrubbed;
        }
        public static MsgType GetMsgType(byte[] arr)
        {
            byte[] subheader = new byte[SUBHEADER_SIZE];
            for (int i = 0; i < SUBHEADER_SIZE; i++)
                subheader[i] = arr[i];
            int iType = BitConverter.ToInt32(subheader, 0);
            MsgType mtType;
            // Also tried: "MemoryStream stream = new MemoryStream(subheader); 
            // int iType = new BinaryReader(stream).ReadInt32();"
            LocalConsole.Instance.Log("iType is " + iType, true);
            switch(iType)
            {
                case (int)MsgType.POS:
                    mtType = MsgType.POS;
                    break;
                case (int)MsgType.STATE:
                    mtType = MsgType.STATE;
                    break;
                case (int)MsgType.STATUS:
                    mtType = MsgType.STATUS;
                    break;
                case (int)MsgType.MSG:  // Default to MSG
                default:
                    mtType = MsgType.MSG;
                    break;
            }
            return mtType;
        }

Java服务器:

    public void run() {
        try (DatagramSocket udpServSock = new DatagramSocket(_port)) {
            DatagramPacket packet = null;
            byte[] byteArr = new byte[HubrisServer.MAX_PACKET_SIZE];
            while (true) {
                packet = new DatagramPacket(byteArr, byteArr.length);
                udpServSock.receive(packet);
                InetAddress clientAdd = packet.getAddress();
                int clientPort = packet.getPort();
                MsgType type = getMsgType(packet.getData());
                String msg = DataToString(scrubSubheader(packet.getData()), true);
                MsgType sendType = HubrisServer.MsgType.STATUS;
                msg = "0";
                byte[] sendArr = assemblePacket(msg.getBytes(), sendType);
                DatagramPacket sendPack = new DatagramPacket(sendArr, sendArr.length, clientAdd, clientPort);
                Thread.sleep(1000);
                udpServSock.send(sendPack);
            }
        } catch ... {
            ...
        }
    }
    /**
     * Assemble a packet with subheader and data
     * @param arr
     * @param type
     * @return packet
     */
    public static byte[] assemblePacket(byte[] arr, MsgType type) {
        ByteBuffer buff = ByteBuffer.allocate(4);
        buff.putInt(type.getValue());
        byte[] subheader = buff.array();
        byte[] packet = new byte[arr.length + subheader.length];
        for(int i = 0; i < packet.length; i++) {
            if(i >= subheader.length)
                packet[i] = arr[i - subheader.length];
            else
                packet[i] = subheader[i];
        }
        return packet;
    }
    /**
     * Scrub the subheader from a byte array and return the scrubbed array
     * @param arr
     * @return
     */
    public static byte[] scrubSubheader(byte[] arr)
    {
        ... similar to C# implementation
    }
    public static MsgType getMsgType(byte[] arr)
    {
        byte[] subArr = new byte[SUBHEADER_SIZE];
        for (int i = 0; i < SUBHEADER_SIZE; i++)
            subArr[i] = arr[i];
        ByteBuffer buff = ByteBuffer.wrap(subArr);
        int iType = buff.getInt();
        MsgType mtType;
        if(iType == MsgType.POS.getValue())
            mtType = MsgType.POS;
        else if (iType == MsgType.STATE.getValue())
            mtType = MsgType.STATE;
        else if (iType == MsgType.STATUS.getValue())
            mtType = MsgType.STATUS;
        else // Default to MSG
            mtType = MsgType.MSG;
        return mtType;
    }

感谢Avo Nappo和VGR,这被确定为一个endian问题。(如果你们中的任何一个提交评论作为答案,我将接受它作为答案(

似乎在Java中默认为Big Endian的字节扣,因此用" .Order(byteorder.little_endian(切换它们"解决了问题。

最新更新