通过UDP套接字发送一个类,这是将数据转换为字节的正确方法吗?

时间:2015-02-19 17:15:45

标签: c# sockets serialization

  • 我的方法“ToByte()”是将数据转换为的正确方法 字节,以便通过Udp发送?

  • 我该如何反过来? (观看“收到的数据包构造函数”)

  • 我应该担心收到的数据包的完整性 避免例外?

    public class GameDataPacket
    {
        private MultiplayerService.Command command_;
        private string nickname_;
        private float x_;
        private float y_;
    
        public GameDataPacket()
        {
            this.command_ = MultiplayerService.Command.Nothing;
            this.nickname_ = "noname";
            this.x_ = 0.0f;
            this.y_ = 0.0f;
        }
    
        // Constructor for received packet
        public GameDataPacket(byte[] data)
        {
            this.command_ = (MultiplayerService.Command)BitConverter.ToInt32(data, 0);
            // How to get those values from the RECEIVED packet?
            this.nickname_ = Encoding.UTF8.GetString(data, ??, ??);
            this.x_ = BitConverter.ToSingle(data, ??); 
            this.y_ = BitConverter.ToSingle(data, ??); 
        }
    

如何将我的信息转换为字节:

public byte[] ToByte()
        {
            // FORMAT
            // |Command|Name|x|y|

            List<byte> result = new List<byte>();

            result.AddRange(BitConverter.GetBytes((int)command_));
            result.AddRange(Encoding.UTF8.GetBytes(nickname_));
            result.AddRange(BitConverter.GetBytes(x_));
            result.AddRange(BitConverter.GetBytes(y_));

            return result.ToArray();
        }

2 个答案:

答案 0 :(得分:2)

因为字符串可以是任何长度,所以您需要发送名称的长度,或者向数据包添加一些内容,以便您检测字符串的结尾。前缀长度可能是最简单和最直接的。

更新了构造函数和To-bytes方法:

    // Constructor for received packet
    public GameDataPacket(byte[] data)
    {

        int packetOffset = 0;

        this.command_ = (MultiplayerService.Command)BitConverter.ToInt32(data, packetOffset);
        packetOffset += 4;

        // read the length (in bytes) of the nickname
        int nickDataLength = BitConverter.ToInt32(data, packetOffset);
        packetOffset += 4;

        // read the nick name
        this.nickname_ = Encoding.UTF8.GetString(data, packetOffset, nickDataLength);
        packetOffset += nickDataLength;
        this.x_ = BitConverter.ToSingle(data,  packetOffset);
        packetOffset += 4;
        this.y_ = BitConverter.ToSingle(data,  packetOffset);
    }

    public byte[] ToByte()
    {
        // FORMAT
        // |Command|NameDataLength|Name|x|y|

        List<byte> result = new List<byte>();

        result.AddRange(BitConverter.GetBytes((int)command_));
        byte[] nicknameBytes = Encoding.UTF8.GetBytes(nickname_);
        result.AddRange(BitConverter.GetBytes(nicknameBytes.Length));
        result.AddRange(nicknameBytes);
        result.AddRange(BitConverter.GetBytes(x_));
        result.AddRange(BitConverter.GetBytes(y_));

        return result.ToArray();
    }

答案 1 :(得分:0)

您可以使用BinaryFormatter ...

[Serializable]
public class MyClass
{
    public int MyProperty { get; set; }
}

// On the sending side...
var myClass = new MyClass { MyProperty = 1 };

byte[] bytes = null;
using (var ms = new MemoryStream())
{
    var bf = new BinaryFormatter();
    bf.Serialize(ms, myClass);
    bytes = ms.ToArray();
}

// On the receiving side...
MyClass other = null;
using (var ms = new MemoryStream(bytes))
{
    var bf = new BinaryFormatter();
    other = (MyClass)bf.Deserialize(ms);
}