[英]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.