C# - 我想将 WPF InkCanvas 发送到套接字(其他客户端)



我想通过服务器将 InkCanvas 笔画发送到其他客户端。
即使我用谷歌搜索也找不到任何提示。

  1. 客户端将数据包发送到服务器。
  2. 服务器将从客户端接收的数据包发送到其他客户端。
  3. 其他客户端将从服务器接收的数据包转换为 StrokeCollection 类型。

客户端代码

public void SendInkCanvas(int roomID, InkCanvas inkCanvas)
{
try
{
MemoryStream memoryStream = new MemoryStream();
inkCanvas.Strokes.Save(memoryStream);
memoryStream.Position = 0;
memoryStream.Flush();
Packet packet = new Packet(PacketType.SendInkCanvas, id);
packet.data.Add("RoomID", roomID);
packet.data.Add("Strokes", memoryStream);
socket.Send(packet.ToBytes());
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
}
}

服务器代码

case PacketType.SendInkCanvas:
int roomIDIC = (int)packet.data["RoomID"];
packet.senderID = "";
packet.data.Remove("RoomID");
// Dictionary<int, Dictionary<string, Socket>> roomClient
foreach (Socket cli in roomClient[roomIDIC].Values)
cli.Send(packet.ToBytes());
break;

其他客户端代码

DrawInkCanvas.Strokes = new StrokeCollection((MemoryStream)packet.data["Strokes"]);

数据包类

[Serializable]
public class Packet
{
#region Variable
public Dictionary<string, object> data;
public int packetInt;
public bool packetBool;
public string senderID;
public PacketType packetType;
#endregion
#region PacketType, SenderID
public Packet(PacketType type, string senderID)
{
data = new Dictionary<string, object>();
this.packetType = type;
this.senderID = senderID;
}
#endregion
#region PacketBytes
public Packet(byte[] packetBytes)
{
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream(packetBytes);
formatter.Binder = new AllowAllAssemblyVersionsDeserializationBinder();
formatter.AssemblyFormat = FormatterAssemblyStyle.Simple;
Packet packet = (Packet)formatter.Deserialize(stream);
stream.Close();
this.data = packet.data;
this.packetInt = packet.packetInt;
this.packetBool = packet.packetBool;
this.senderID = packet.senderID;
this.packetType = packet.packetType;
}
#endregion
#region Packet To Bytes
public byte[] ToBytes()
{
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
formatter.AssemblyFormat = FormatterAssemblyStyle.Simple;
formatter.Serialize(stream, this);
byte[] bytes = stream.ToArray();
stream.Close();
return bytes;
}
#endregion
}
#region PacketType
public enum PacketType
{
SendInkCanvas
}
#endregion

问题是您正在尝试发送实际MemoryStream

MemoryStream是一种引用类型,这意味着其他对象仅被赋予对应用程序内存中MemoryStream地址的引用,而不是被赋予它们自己的整个对象副本。

当你执行packet.data.Add("Strokes", memoryStream);时,从技术上讲,添加到字典中的是MemoryStream对象的地址。因此,当您ToBytes()并序列化Packet(以及随之而来的data字段(时,只会序列化MemoryStream的内存地址,而不是实际内容。反序列化Packet时,无法从新上下文访问现有MemoryStream

相反,您要做的是将MemoryStream的内容添加到Packet。为此,请将MemoryStream写入Byte数组,然后将其添加到data数组中。Byte是值类型,而不是引用类型,因此它的整个值被复制到data中,并将随之序列化。

相关内容

最新更新