在套接字上进行二进制序列化

时间:2014-02-14 15:12:07

标签: c# sockets serialization binary

我目前正在为我的C ++服务器实现一个c#客户端。通信协议是二进制的。在服务器端,没有问题,因为二进制化只是memcpy的问题。但是,我的C#客户端无法通过套接字发送数据。

首先,这是我的数据结构:

标题:

[Serializable]
public class Header
{
    public UInt32 UserId { get; set; }
    public UInt16 CheckSum { get; set; }
    public byte Status { get; set; }
    public byte Command { get; set; }
    public byte Device { get; set; }
    public byte Method { get; set; }
    public byte KeepAlive { get; set; }
    public byte Osef { get; set; }
    public Header()
    {
        UserId = 0;
        CheckSum = 0;
        Status = 0;
        Command = 0;
        Device = 0;
        Method = 0;
        KeepAlive = 0;
        Osef = 0;
    }
    public static UInt16 Size()
    {
            return Convert.ToUInt16(sizeof(byte) * 6 + sizeof(UInt32) + sizeof(UInt16));
    }

    internal void write(Stream stream)
    {
        BinaryWriter writer = new BinaryWriter(stream);

        writer.Write(UserId);
        writer.Write(CheckSum);
        writer.Write(Status);
        writer.Write(Command);
        writer.Write(Device);
        writer.Write(Method);
        writer.Write(KeepAlive);
        writer.Write(0); //alignement
    }

    internal void read(Stream stream)
    {
        BinaryReader reader = new BinaryReader(stream);

        UserId = reader.ReadUInt32();
        CheckSum = reader.ReadUInt16();
        Status = reader.ReadByte();
        Command = reader.ReadByte();
        Device = reader.ReadByte();
        Method = reader.ReadByte();
        KeepAlive = reader.ReadByte();
        reader.ReadByte(); //alignement
    }
}

首先包含标题的数据结构:

[Serializable]
class UserPass
{
    public Header Header { get; set; }
    public UInt16 User_checkSum { get; set; }
    public byte[] Username { get; set; }
    public UInt16 Pass_checkSum { get; set; }
    public byte[] Password { get; set; }

    public UInt16 Size()
    {
        return Convert.ToUInt16((sizeof(byte) * 128) + (sizeof(byte) * 128) + sizeof(UInt16) * 2);
    }

    public UserPass()
    {
        Header = new Header();
        User_checkSum = 0;
        Username = new byte[128];
        Pass_checkSum = 0;
        Password = new byte[128];
    }

    internal void write(Stream stream)
    {
        BinaryWriter writer = new BinaryWriter(stream);

        Header.write(stream);
        writer.Write(User_checkSum);
        writer.Write(Username, 0, 128);
        writer.Write(Pass_checkSum);
        writer.Write(Password, 0, 128);
    }

    internal void read(Stream stream)
    {
        BinaryReader reader = new BinaryReader(stream);

        Header.read(stream);
        User_checkSum = reader.ReadUInt16();
        Username = reader.ReadBytes(User_checkSum);
        Pass_checkSum = reader.ReadUInt16();
        Password = reader.ReadBytes(Pass_checkSum);
    }
}

我使用Header和UserPass的write函数编写数据,并将NetworkStream作为参数传递给我使用GetStream从我的套接字转换。

问题是服务器正确接收标头,每个字段包含客户端初始化的值,但其余数据用零填充。

  • 我尝试过使用相同的BinaryWriter对象。没有解决它。

  • 我尝试过使用流式刷新功能。没有解决它

  • 我尝试了一些花哨的库和protobuf-net库。事情变得更糟,标题充满了胡言乱语。

什么'有趣的是,当我尝试使用相同的方法来序列化这些结构的文件,要么是在图书馆或结构的写入方法,它工作正常,存储在文件中的数据是正确的,但当我通过套接字发送它时,它失败了。

1 个答案:

答案 0 :(得分:0)

基本上,你的“对齐”是写一个int而不是一个字节。

在Header类的Write()方法中,更改...

    writer.Write(0); //alignement

...到...

    writer.Write((byte)0); //alignement

然后您的Read似乎工作正常,而任何其他问题都与您的消息或服务器端读取有关。