我目前正在为我的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库。事情变得更糟,标题充满了胡言乱语。
什么'有趣的是,当我尝试使用相同的方法来序列化这些结构的文件,要么是在图书馆或结构的写入方法,它工作正常,存储在文件中的数据是正确的,但当我通过套接字发送它时,它失败了。
答案 0 :(得分:0)
基本上,你的“对齐”是写一个int而不是一个字节。
在Header类的Write()方法中,更改...
writer.Write(0); //alignement
...到...
writer.Write((byte)0); //alignement
然后您的Read似乎工作正常,而任何其他问题都与您的消息或服务器端读取有关。