我正在尝试了解C#中的套接字,并决定为练习创建一个多人游戏。虽然我已经在套接字发送中走得很远,但是我遇到一个奇怪的问题,布尔值在从其他客户端接收和反序列化我的类之后总是变为true。
问题出现在这里:
void OnDataReceived(object sender, ConnectionEventArgs e)
{
Connection con = (Connection)e.SyncResult.AsyncState;
Game.ScoreBoard[currentPlayer] = Serializer.ToScoreCard(con.buffer); //Here
...
}
Game.ScoreBoard [currentPlayer] .Local 总是变为现实,我根本不确定问题是什么。其他值似乎工作正常。 Connection是一个包含IP,套接字和管理连接等的类。缓冲区大小目前是30 000,因为我尝试扩大它以确保不是问题。
以下是该课程的相关信息:
public ScoreCard(SerializationInfo info, StreamingContext context)
{
name = (string)info.GetValue("Name", typeof(string));
played = (bool[])info.GetValue("Played", typeof(bool[]));
scores = (int[])info.GetValue("Scores", typeof(int[]));
bonusScore = (int)info.GetValue("bonusScore", typeof(int));
local = (bool)info.GetValue("Local", typeof(bool));
}
和
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Scores", scores, typeof(int[]));
info.AddValue("Played", played, typeof(bool[]));
info.AddValue("Name", name, typeof(string));
info.AddValue("bonusScore", bonusScore, typeof(int));
info.AddValue("Local", local, typeof(bool));
}
这是序列化程序类:
static class Serializer
{
public static byte[] ToArray(object data)
{
MemoryStream stream = new MemoryStream();
BinaryFormatter b = new BinaryFormatter();
b.Serialize(stream, data);
return stream.ToArray();
}
public static ScoreCard ToScoreCard(byte[] data)
{
ScoreCard sc;
MemoryStream stream = new MemoryStream(data);
BinaryFormatter b = new BinaryFormatter();
sc = (ScoreCard)b.Deserialize(stream);
return sc;
}
}
我不知道该怎么做,或者即使所提供的信息足以让您能够解决我的问题。如有必要,我可以提供更多信息。我觉得很奇怪,看起来只有布尔值无法正常工作。
编辑:我发现了问题,像往常一样,这是一个简单的愚蠢错误。哦,我学会了至少制作自己的二进制格式。谢谢你们:)
答案 0 :(得分:1)
BinaryFormatter的性能非常糟糕。它序列化的每个对象都有大量的开销,根据我的经验,格式化程序需要>用二进制序列化对象的40秒可以在< 1秒由自定义二进制文件编写。
您可能需要考虑这个问题:
static class Serializer
{
public static byte[] MakePacket(ScoreCard data)
{
MemoryStream stream = new MemoryStream();
using (StreamWriter sw = new StreamWriter(stream)) {
sw.Write(1); // This indicates "version one" of your data format - you can modify the code to support multiple versions by using this
sw.Write(data.Name);
sw.Write(data.scores.Length);
foreach (int score in data.scores) {
sw.Write(score);
}
sw.Write(data.played.Length);
foreach (bool played in data.played) {
sw.Write(played );
}
sw.Write(data.bonusScore);
sw.Write(data.local);
}
return stream.ToArray();
}
public static ScoreCard ReadPacket(byte[] data)
{
ScoreCard sc = new ScoreCard();
MemoryStream stream = new MemoryStream(data);
using (StreamReader sr = new StreamReader(stream)) {
int ver = sr.ReadInt32();
switch (ver) {
case 1:
sc.name = sr.ReadString();
sc.scores = new int[sr.ReadInt32()];
for (int i = 0; i < sc.scores.Length; i++) {
sc.scores[i] = sr.ReadInt32();
}
sc.played = new bool[sr.ReadInt32()];
for (int i = 0; i < sc.scores.Length; i++) {
sc.played [i] = sr.ReadBool();
}
sc.BonusScore = sr.ReadInt32();
sc.Local = sr.ReadBool();
break;
default:
throw new Exception("Unrecognized network protocol");
}
}
return sc;
}
}