你这个_msgBuff 的长度随便定义,然后把真实的长度recCount 再定一个byte[] ?即 byte[] b = new byte[recCount ] ,但是里面是空的啊,难道还要遍历 _msgBuff,给 b 赋值?
你这个_msgBuff 的长度随便定义,然后把真实的长度recCount 再定一个byte[] ?即 byte[] b = new byte[recCount ] ,但是里面是空的啊,难道还要遍历 _msgBuff,给 b 赋值? _msgBuff的长度不是随便定义的,你需要定义一个足够大的空间当做缓冲区来接收网卡来的数据包. 定义小了可是会将包截断的,需要读取多次然后自己拼接. 获取到长度后,当然是循环赋值,但是不用遍历,循环recCount次就够了,不要循环_msgBuff.Length次
把 class patOrder放到单独的类库项目中,客户端和服务端都引用它
你这个_msgBuff 的长度随便定义,然后把真实的长度recCount 再定一个byte[] ?即 byte[] b = new byte[recCount ] ,但是里面是空的啊,难道还要遍历 _msgBuff,给 b 赋值? _msgBuff的长度不是随便定义的,你需要定义一个足够大的空间当做缓冲区来接收网卡来的数据包. 定义小了可是会将包截断的,需要读取多次然后自己拼接. 获取到长度后,当然是循环赋值,但是不用遍历,循环recCount次就够了,不要循环_msgBuff.Length次 byte[] _msgBuff = new byte[_maxPacket]; int a = clientSkt.Receive(_msgBuff); byte[] _msgBuff1 = new byte[a]; for (int i = 0; i < a; i++) { _msgBuff1[i] = _msgBuff[i]; } MemoryStream memory = new MemoryStream(_msgBuff1);//使用内存流来存这些byte[] memory.Position = 0; BinaryFormatter b = new BinaryFormatter(); object o = b.Deserialize(memory); patOrder po = ((patOrder)o); memory.Close(); 还是不行的
neng 我客户端和服务器端是两个程序,不可能公用一个类库啊
memory.Position = 0;//这句MS没用 object o = b.Deserialize(memory);//还是这句报错? 你先传一个datatable,看能不能反序列化,如果能,找找自定义类的问题遇到问题先分解,一步一步解决. 不要老想一步到位啊.
首先我真要先感谢下你,一直耐心回答。其次,关于这个问题我真的是太郁闷了,说出你都不信,我datatable进行序列化,然后传到服务器反序列化,一开始也是这个问题,后来别人说改成 byte[] buff = memory.ToArray();而不是memory.GetArray();最后居然好了,请一个程序中,我再次用同样方法传递datatable又失败了object o = b.Deserialize(memory);报错:“b.Deserialize(memory)”引发了“System.Runtime.Serialization.SerializationException”类型的异常。郁闷死我了
class patOrder
{
private string pAT_NAME; public string PAT_NAME
{
get { return pAT_NAME; }
set { pAT_NAME = value; }
} private string pAT_SEX; public string PAT_SEX
{
get { return pAT_SEX; }
set { pAT_SEX = value; }
}
}
这个类在服务器端和客户端都有的,而且是一摸一样啊
引发了“System.Runtime.Serialization.SerializationException”类型的异常 。这次正好系统的弄清楚。希望大家赐教!
byte[] _msgBuff = new byte[_maxPacket];
clientSkt.Receive(_msgBuff);
我自定义_maxPacket是64* 1024,所以_msgBuff 前面356位是和客户端buff是一样的,只是剩下的空间他全部是0,不知道这个在转换的时候会不会是出问题的原因?
缓冲区是缓冲区,数据byte[ ]是数据byte[ ]
你不能直接把缓冲区当数据啊
后面那么多无效的0,你让编译器怎么转
然后根据这个长度,new一个byte[ ]
循环赋值
然后再转
缓冲区是缓冲区,数据byte[ ]是数据byte[ ]
你不能直接把缓冲区当数据啊
后面那么多无效的0,你让编译器怎么转
那么,我怎么保持byte[] 的长度一致啊?
我在服务器端接收时要定义一个byte[],长度怎么和传过来的一致?
你这个_msgBuff 的长度随便定义,然后把真实的长度recCount 再定一个byte[] ?即 byte[] b = new byte[recCount ] ,但是里面是空的啊,难道还要遍历 _msgBuff,给 b 赋值?
你这个_msgBuff 的长度随便定义,然后把真实的长度recCount 再定一个byte[] ?即 byte[] b = new byte[recCount ] ,但是里面是空的啊,难道还要遍历 _msgBuff,给 b 赋值?
_msgBuff的长度不是随便定义的,你需要定义一个足够大的空间当做缓冲区来接收网卡来的数据包.
定义小了可是会将包截断的,需要读取多次然后自己拼接.
获取到长度后,当然是循环赋值,但是不用遍历,循环recCount次就够了,不要循环_msgBuff.Length次
你这个_msgBuff 的长度随便定义,然后把真实的长度recCount 再定一个byte[] ?即 byte[] b = new byte[recCount ] ,但是里面是空的啊,难道还要遍历 _msgBuff,给 b 赋值?
_msgBuff的长度不是随便定义的,你需要定义一个足够大的空间当做缓冲区来接收网卡来的数据包.
定义小了可是会将包截断的,需要读取多次然后自己拼接.
获取到长度后,当然是循环赋值,但是不用遍历,循环recCount次就够了,不要循环_msgBuff.Length次
byte[] _msgBuff = new byte[_maxPacket];
int a = clientSkt.Receive(_msgBuff);
byte[] _msgBuff1 = new byte[a];
for (int i = 0; i < a; i++)
{
_msgBuff1[i] = _msgBuff[i];
}
MemoryStream memory = new MemoryStream(_msgBuff1);//使用内存流来存这些byte[]
memory.Position = 0;
BinaryFormatter b = new BinaryFormatter();
object o = b.Deserialize(memory);
patOrder po = ((patOrder)o);
memory.Close();
还是不行的
我客户端和服务器端是两个程序,不可能公用一个类库啊
object o = b.Deserialize(memory);//还是这句报错?
你先传一个datatable,看能不能反序列化,如果能,找找自定义类的问题遇到问题先分解,一步一步解决.
不要老想一步到位啊.
首先我真要先感谢下你,一直耐心回答。其次,关于这个问题我真的是太郁闷了,说出你都不信,我datatable进行序列化,然后传到服务器反序列化,一开始也是这个问题,后来别人说改成 byte[] buff = memory.ToArray();而不是memory.GetArray();最后居然好了,请一个程序中,我再次用同样方法传递datatable又失败了object o = b.Deserialize(memory);报错:“b.Deserialize(memory)”引发了“System.Runtime.Serialization.SerializationException”类型的异常。郁闷死我了
每个包的收发都要校验完整性和合法性
客户端开了10个线程,每个线程每秒访问10次,运行24小时,失败率都是个位数
你的通信又是怎么测试的?不会就是客户端发一个数,服务端接收到了,就完事了吧
我是这么想的,客户端和服务器端数据交互要通过字节流,那么,我在客户端发送的字节流与服务器端接收的字节流完全一致,那么可以说在传递过程中是没有问题的,只是不知道为什么在反序列化的时候会出现“b.Deserialize(memory)”引发了“System.Runtime.Serialization.SerializationException”类型的异常的问题,那么我可以说是在反序列化的过程中出错的啊
MemoryStream memory = new MemoryStream(_msgBuff, 0, len);其他地方倒是没有问题
为什么不能公用一个类库,将需要序列化的数据类型做在类库A中, 服务器和客户端都引用A.dll就可以保证序列化和反序列化的数据类型统一。
先把datatable传好使了,再弄你那个自定义类.
如果是相同定义的不同类型序列化问题,可以试试fastCSharp patOrder po = new patOrder { PAT_NAME = "大Name", PAT_SEX = "1" };
byte[] data = fastCSharp.setup.cSharp.serialize.dataSerialize.Get(po);
patOrder po2 = fastCSharp.setup.cSharp.serialize.deSerialize.Get<patOrder>(data);
如果是普通的DataSet/DataTable序列化可以试试 byte[] data = fastCSharp.data.dataSet.Serialize(set);
DataSet set2 = fastCSharp.data.dataSet.DeSerialize(data); byte[] data = fastCSharp.data.dataTable.Serialize(set);
DataSet set2 = fastCSharp.data.dataTable.DeSerialize(data);如果是网络环节问题,可以试试fastCSharp的TCP调用服务,做好配置以后,你就只需要关心你的业务逻辑了。
1. 网络传输
楼上已经说了很多了,我觉得检查的办法就是,简单一点,在发送方获取发送的实际字节数 buff.Length 和接收方实际收到的 memory.ToArray().Length,这两个是否相等。如果是相等的话,先不考虑网络传输的问题。
2. 反序列化
这一部分主要确定类型的定义问题,首先,发送方和接收方都引用了同一个 Library,并且当前你需要反序列化的对象类型是在这个 Library 定义的(如果用 VS 的话,在类名上使用转到定义,避免你认为是引用的 Library 里面的类型而实际上使用的是自己定义的类型),然后,这个类型里面的属性、公有局部变量的所引用的类型所在类库在发送方和接收方也是被引用的。
通常情况下这样就可以发现问题了,但是如果这两个都检查了仍然不能发现问题的原因,把抓到的 SerializationException 的全部能容以及 InnerException 都打出来看一下。
首先我真要先感谢下你,一直耐心回答。其次,关于这个问题我真的是太郁闷了,说出你都不信,我datatable进行序列化,然后传到服务器反序列化,一开始也是这个问题,后来别人说改成 byte[] buff = memory.ToArray();而不是memory.GetArray();最后居然好了,请一个程序中,我再次用同样方法传递datatable又失败了object o = b.Deserialize(memory);报错:“b.Deserialize(memory)”引发了“System.Runtime.Serialization.SerializationException”类型的异常。郁闷死我了因为GetBuffer起始读取位置是根据memorystream的position的,而toarray不需要。
命名空间也必须一样。如果工程在你的电脑上都能得到,其实你在另一个工程中“添加现有项”,然后选择另一个工程里的这个文件然后选择“引用”(注意是下来列表中的“引用”,而不是“添加”),那么两个工程就使用同一个文件进行编译了。当然单独把这个文件建一个独立的工程发布为DLL然后其它两个工程都引用这个DLL,也可以。只不过也太繁琐了。
我是这么想的,客户端和服务器端数据交互要通过字节流,那么,我在客户端发送的字节流与服务器端接收的字节流完全一致,那么可以说在传递过程中是没有问题的,只是不知道为什么在反序列化的时候会出现“b.Deserialize(memory)”引发了“System.Runtime.Serialization.SerializationException”类型的异常的问题,那么我可以说是在反序列化的过程中出错的啊不一致啊,你在服务器端的数据不是有一堆0吗?
二进制流“0”不包含有效的 BinaryHeader。这可能是由于无效流,或由于在序列化和反序列化之间的对象版本更改。
这个是在客户端接受了服务器端的字节流进行反序列化是出现的错误