我正在尝试将对象列表发送到另一台计算机。我是套接字的新手,但我已经尝试了很多东西。最后,我总是遇到错误,无法克服错误。
我发送的对象列表是包含函数,变量和属性的类。我已将[Serializable]放在此类的顶部。
每次客户端执行某个操作时,它都会将San_Change更改为true并启动客户端线程。
我已在下面附上我的代码,我们将不胜感激。
public void Create_Network_Thread(string Host_Or_Client)
{
//This creates a network thread and starts it.
//Host
if (Host_Or_Client == "Host")
{
Host_networkThread = new Thread(new ThreadStart(Host_Network_Thread_Start));
Host_networkThread.Start();
}
//Client
else
{
Client_networkThread = new Thread(new ThreadStart(Client_Network_Thread_Start));
Client_networkThread.Start();
}
}
private void Host_Network_Thread_Start()
{
try
{
TcpListener serverSocket = new TcpListener(8888);
TcpClient clientSocket = default(TcpClient);
serverSocket.Start();
clientSocket = serverSocket.AcceptTcpClient();
while (true)
{
object San_Object;
NetworkStream networkStream = clientSocket.GetStream();
byte[] bytesFrom = new byte[clientSocket.Available];
networkStream.Read(bytesFrom, 0, clientSocket.Available);
San_Object = ByteArrayToObject(bytesFrom);
San_List = (List<San>)San_Object;
byte[] sendBytes = ObjectToByteArray(San_Object);
networkStream.Write(sendBytes, 0, sendBytes.Length);
networkStream.Flush();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private void Client_Network_Thread_Start()
{
while (true)
{
if (San_Change == true)
{
San_Change = false;
try
{
System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();
object San_Object = San_List;
string cur_ip = "";
clientSocket.Connect(cur_ip, 8888);
NetworkStream serverStream = clientSocket.GetStream();
byte[] outStream = ObjectToByteArray(San_Object);
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
byte[] inStream = new byte[(int)clientSocket.ReceiveBufferSize];
San_Object = ByteArrayToObject(inStream);
San_List = (List<San>)San_Object;
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}
private byte[] ObjectToByteArray(Object obj)
{
if (obj == null)
return null;
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, obj);
return ms.ToArray();
}
private Object ByteArrayToObject(byte[] arrBytes)
{
MemoryStream memStream = new MemoryStream();
BinaryFormatter binForm = new BinaryFormatter();
memStream.Write(arrBytes, 0, arrBytes.Length);
memStream.Seek(0, SeekOrigin.Begin);
Object obj = (Object)binForm.Deserialize(memStream);
return obj;
}
}
当发生这种情况时:
忘了添加它,但是当我运行它时,因为代码失败了。这是信息,希望这会有所帮助。再次感谢。
e {System.Runtime.Serialization.SerializationException: Binary stream '0' does not contain a valid BinaryHeader. Possible causes are invalid stream or object version change between serialization and deserialization.
at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)
at San_Player_V2.Game.ByteArrayToObject(Byte[] arrBytes) in San_Player_V2\Game.cs:line 573
at San_Player_V2.Game.Client_Network_Thread_Start() in San_Player_V2\Game.cs:line 477} System.Exception {System.Runtime.Serialization.SerializationException}
答案 0 :(得分:2)
通常的问题:
我个人也会说使用BinaryFormatter是有问题的,但这不是最大的问题。
请参阅http://marcgravell.blogspot.com/2013/02/how-many-ways-can-you-mess-up-io.html
答案 1 :(得分:0)
这似乎是你双重工作/重新发明轮子,那就是:
- 将对象转换为字节数组
- 你通过流发送出来。
醇>
相反,你尝试这样的事情:
- 将您的套接字链接到ObjectOutputStream
- 使用ObjectOutputStream直接编写对象并使用标准API
醇>
处理序列化末尾的对象并在另一端反序列化它(当你使用ObjectInputStream接收它时)。
答案 2 :(得分:0)
所以我认为我找到了答案。什么是将对象转换为xml然后将该xml转换为字符串。将该字符串作为字符串发送到套接字然后在另一端将其重新转换为xml然后再返回到对象。我附上了一个小例子。
这是在对象中并调用xml它。
public string ToXML()
{
var stringwriter = new System.IO.StringWriter();
var serializer = new XmlSerializer(this.GetType());
serializer.Serialize(stringwriter, this);
return stringwriter.ToString();
}
调用此方法将xml转换回选择对象。
public static Object_Name_Here LoadFromXMLString(string xmlText)
{
var stringReader = new System.IO.StringReader(xmlText);
var serializer = new XmlSerializer(typeof(Object_Name_Here));
return serializer.Deserialize(stringReader) as Object_Name_Here;
}
如果有人有更好的想法,那就是我正在做的事情请分享一个好榜样。
谢谢!