C# .NET智能卡-序列化/反序列化远程对象。输入流的格式无效
我使用的是.NET智能卡,它与.NET远程处理的概念相同 因此,我的智能卡(作为服务器)具有以下服务:C# .NET智能卡-序列化/反序列化远程对象。输入流的格式无效,c#,.net,serialization,smartcard,gemalto,C#,.net,Serialization,Smartcard,Gemalto,我使用的是.NET智能卡,它与.NET远程处理的概念相同 因此,我的智能卡(作为服务器)具有以下服务: public class MyService : MarshalByRefObject { string a = "abC"; public byte[] MySampleMethod() { MyService obj = new MyService(); return help.ObjectToByteArray( obj);
public class MyService : MarshalByRefObject
{
string a = "abC";
public byte[] MySampleMethod()
{
MyService obj = new MyService();
return help.ObjectToByteArray( obj);
}}}
这是ObjectToByteArray(obj)
至于客户:
public static void Main()
{
// create and register communication channel
APDUClientChannel channel = new APDUClientChannel();
ChannelServices.RegisterChannel(channel);
// get the referenc to remote object
MyService service = (MyService)Activator.GetObject(typeof(MyService), URL);
// invoke the remote method
byte[] result = service.MySampleMethod();
MyService obj = ByteArrayToObject(result);
Console.WriteLine(result[0]);
Console.ReadLine();
// unregister the communication channel
ChannelServices.UnregisterChannel(channel);
}
ByteArrayObject
public static MyService ByteArrayToObject(byte[] arrBytes)
{
MemoryStream memStream = new MemoryStream(0);
BinaryFormatter binForm = new BinaryFormatter();
memStream.Write(arrBytes, 0, arrBytes.Length);
memStream.Seek(0, SeekOrigin.Begin);
//memStream.Position = 0;
MyService obj = (MyService)binForm.Deserialize(memStream);
return obj;
}
问题是何时要反序列化对象
我测试这个字符串“ABCDE”,在卡中序列化它,结果是:
1C-5D-D2-00-27-11-02-00-00-00-05-00-00-00-05-00-00-00-00-01-41-00-42-00-43-00-44-00-45-00
当我在我的电脑上序列化它时,结果是:
00-01-00-00-FF-FF-FF-FF-01-00-00-00-00-00-00-06-01-00-00-00-00-05-41-42-43-44-45-0B
因此,在我的PC应用程序中,反序列化第二个字符串效果很好,但当我反序列化第一个字符串(来自智能卡)时,我得到:
“输入流不是有效的二进制格式。起始内容(以字节为单位)为:1C-5D-D2-00-27-11-02-00-00-00-05-00-00-00-05-00-00…”
Gemalto.NET智能卡仅支持通过引用进行封送,因此可以在客户端访问服务器中的任何基元和结构类型,而无需序列化,因为您已经通过远程调用对对象进行了引用: 因此,首先注册您的服务:
public class MyServer
{
/// <summary>
/// specify the exposed remote object URI.
/// </summary>
private const string REMOTE_OBJECT_URI = "MyService.uri";
/// <summary>
/// Register the server onto the card.
/// </summary>
/// <returns></returns>
public static int Main()
{
// Register the channel the server will be listening to.
ChannelServices.RegisterChannel(new APDUServerChannel());
// Register this application as a server
RemotingConfiguration.RegisterWellKnownServiceType(typeof(MyService), REMOTE_OBJECT_URI, WellKnownObjectMode.Singleton);
return 0;
}
}
现在在客户端应用程序中,您将拥有对服务对象的引用,并且可以正常调用这些方法:
public class MyClient
{
private const string URL = "apdu://selfdiscover/MyService.uri";
public static void Main()
{
// create and register communication channel
APDUClientChannel channel = new APDUClientChannel();
ChannelServices.RegisterChannel(channel);
// get the referenc to remote object
MyService service = (MyService)Activator.GetObject(typeof(MyService), URL);
Console.WriteLine(service.MySampleMethod());
MyService.Person person = service.getPerson();
Console.WriteLine(person.getName());
Console.WriteLine(person.getId());
Console.ReadLine();
// unregister the communication channel
ChannelServices.UnregisterChannel(channel);
}
}
上面的十六进制字符串中缺少了“T”:P,说真的,我不是.NET卡专家,但是客户机如何知道序列化了哪种类型的对象?如果可能的话,请显示完整的二进制格式。你说的“客户端如何知道”是什么意思,实际上我在客户端添加了server.exe的引用,如果这是你要求的,你有更多的数据吗?上面的“起始内容”中缺少第一个字节,它似乎是某种类型的指示符,它以
(T)ypeLoadSTEx
的ASCII编码开始。。。嗯,可能是某种异常而不是对象?我试图序列化卡片中的字符串:“ABCDE”,结果是:1C-5D-D2-00-27-11-02-00-00-00-00-05-00-00-00-01-41-00-42-00-43-00-44-00-45-00,而在我的电脑上序列化它的结果是:00-01-00-00-00-FF-FF-FF-01-00-00-00-00-06-01-00-00-00-05-41-42-43-44-45-0B。因此,在我的PC应用程序中,反序列化第二个字符串效果很好,但当我反序列化第一个字符串(来自智能卡)时,我得到了:“输入流不是有效的二进制格式。起始内容(以字节为单位)是:1C-5D-D2-00-00-27-11-02-00-00-00-05-00-00-00-00-00…”哼,这里的大多数人无法在.NET卡上调试,您现在输入的十六进制字符串与之前显示的完全不同。NET智能卡还没有出现(据我所知),所以回答这个问题可能很棘手。
public class MyService : MarshalByRefObject
{
public struct Person
{
public string name;
public int id;
public Person(int id, string name)
{
this.name = name;
this.id = id;
}
public string getName()
{
return this.name;
}
public int getId()
{
return this.id;
}
}
public string MySampleMethod()
{
return "This is return String";
}
public Person getPerson()
{
Person person = new Person(15, "Wajdy");
return person;
}
}
public class MyClient
{
private const string URL = "apdu://selfdiscover/MyService.uri";
public static void Main()
{
// create and register communication channel
APDUClientChannel channel = new APDUClientChannel();
ChannelServices.RegisterChannel(channel);
// get the referenc to remote object
MyService service = (MyService)Activator.GetObject(typeof(MyService), URL);
Console.WriteLine(service.MySampleMethod());
MyService.Person person = service.getPerson();
Console.WriteLine(person.getName());
Console.WriteLine(person.getId());
Console.ReadLine();
// unregister the communication channel
ChannelServices.UnregisterChannel(channel);
}
}