簡體   English   中英

套接字上的二進制序列化

[英]Binary serializing on sockets

我目前正在為我的C ++服務器實現ac#客戶端。 通信協議是二進制的。 在服務器端,這是沒有問題的,因為二進制序列化只是一個簡單的問題。 但是,我的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的寫入功能寫入數據,並傳遞NetworkStream作為我使用GetStream從套接字轉換的參數。

問題在於服務器正確接收了標頭,每個字段都包含客戶端初始化的值,但是其余數據填充為零。

  • 我曾嘗試為兩者使用相同的BinaryWriter對象。 沒有解決。

  • 我已經嘗試使用流沖洗。 沒有解決

  • 我嘗試了一些精美的庫和protobuf-net庫。 事情變得更糟了,標題充滿了胡言亂語。

有趣的是,當我嘗試使用相同的方法(即結構的庫或寫方法)將這些結構序列化為文件時,它可以正常工作,存儲在文件中的數據是正確的,但是當我通過套接字發送它,它失敗。

基本上,您的“對齊”是寫一個int而不是一個字節。

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

    writer.Write(0); //alignement

...至...

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

這樣一來,您的閱讀似乎就可以正常工作,而其他任何問題都與您的消息傳遞或服務器端閱讀有關。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM