Data movement, serialization
This article describes two classes, binaryformatter, and SOAPFormatter classes that transmit serialized data over network. These classes can convert the instances of the class into byte stream through the network to the remote system, or convert to the original data.
First, use serialization class
Serialized a class and need three steps through network transmission:
1. Create a class to serialize into a library object.
2. Write a sender to create an instance to serialize classes and send it.
3. Write a receiver read data from the stream and recreate the original serialization class.
1 Write the class to serialize
Each class to transfer data over network must use the [Serializable] tab in the original code file. This indicates that all data in the class will be serialized during transmission. The following shows how to create a class that can be serialized.
Using system;
[Serializable]
Public Class SeriaMPloyee
{
Public int equployeid
Public String lastname;
Public string firstname;
Public int yearsservice;
Public Double Salary;
Public serialemployee ()
{
EmployeeID = 0;
Lastname = NULL;
Firstname = NULL;
Yearsservice = 0;
SALARY = 0.0;
}
}
In order to use this class to transmit data, you must now create a library file:
CSC / T: Library SerialEmployee.cs
2 Write a transmission program
After creating a data class, you can create a program to transfer data. You can use the BinaryFormatter and the SOAPFormatter class to serialize the data.
BinaryFormatter will sequence data into binary stream. Often in actual data, add some information, such as class name, and version number information.
You can also use the SOAPFormatter class to use the XML format to transfer data. The advantage of using XML is that data can be delivered between any system and program.
The first instance of a stream must be created to pass the data. Can be any type of stream, including FileStream, MemoryStream, NetworkStream. You can then create a serialization class, use the serialize () method to pass the data through the stream object:
Stream Str = New FileStream ("Testfile.bin", FileMode.create, FileAccess.Readwrite;
IFORMATTER FORMATTER = New BinaryFormatter ();
Formatter.Serialize (STR, DATA);
The iFormatter class creates an instance of a class for serialization (BinaryFormatter or SOAPFormatter), using the serialize () class to sequence data
Using system;
Using system.io;
Using system.runtime.serialization;
Using system.Runtime.Serialization.formatters.soap;
Class SOAPTEST
{
Public static void main ()
{
SerialEmployee EMP1 = New SerialEmployee ();
SerialEmployee EMP2 = New SerialEmployee ();
EMP1.EMPLOYEEID = 1;
Emp1.lastname = "blum"; Emp1.firstname = "katie jane";
EMP1.YEARSSERVICE = 12;
EMP1.SAlary = 35000.50;
EMP2.EMPLOYEEID = 2;
Emp2.lastname = "blum";
EMP2.FIRSTNAME = "JESSICA";
EMP2.YEARSSERVICE = 9;
EMP2.SAlary = 23700.30;
Street Str = New FileStream ("soaptest.xml", filemode.create,
FileAccess.readwrite;
IFORMATTER FORMATTER = New soapFormatter ();
Formatter.Serialize (STR, EMP1);
Formatter.Serialize (STR, EMP2);
Str.close ();
}
}
SoapFormatter System.Runtime.Serialization.Formatters.Soap namespace contained in the class, BinaryFormatter class contains namespace System.Runtime.Serialization.Formatters.Binary, Iformatter interface contains namespace System.Runtime.Serialization.
Compiling code: csc /r:serialemployee.dll soaptest.cs
After running the soaptest.exe program, you can view the resulting soaptest.xml file
XMLns: XSD = "http://www.w3.org/2001/xmlschema" xmlns: soap-enc = â "http://schemas.xmlsoap.org/soap/encoding/" XMLns: soap-env = â "http://schemas.xmlsoap.org/soap/Envelope/" XMLns: CLR = â "http://schemas.microsoft.com/soap/encoding/clr/1.0" soap-env: encodingstyle = â "http://schemas.xmlsoap.org/soap/encoding/"> "http://schemas.microsoft.com/cll/assem/serialemployee, Version=0. 0.0.0% 2C% 20CULTURE% 3DNEUTRAL% 2C% 20PublicKeyToken% 3DNULL "> Soap-env: body> Soap-env: envelope> XMLns: XSD = "http://www.w3.org/2001/xmlschema" xmlns: soap-enc = â "http://schemas.xmlsoap.org/soap/encoding/" XMLns: soap-env = â "http://schemas.xmlsoap.org/soap/Envelope/" XMLns: CLR = â "http://schemas.microsoft.com/soap/encoding/clr/1.0" soap-env: encodingstyle = â "http://schemas.xmlsoap.org/soap/encoding/"> "http://schemas.microsoft.com/cll/assem/serialemployee, Version=0. 0.0.0% 2C% 20CULTURE% 3DNEUTRAL% 2C% 20PublicKeyToken% 3DNULL "> a1: serialemployee> Soap-env: body> Soap-env: envelope> You can find how SOAP is defined for each data element in the serialization class. A payable important XML data characteristics are as follows: "http://schemas.microsoft.com/cll/assem/serialemployee, Version=0.â0.0.0., CULTURE=NEUTRAL, PublicKeyToken=NULL"> Here, the data defined in XML uses the actual class name of the serialized data class. If the receiver uses another different class name, the XML data read from the stream does not match. Class does not match, read will fail. The following code shows how to serialize data and transfer the data to the remote system. Using system; Using system.net; Using system.net.sockets; Using system.runtime.serialization; Using system.runtime.serialization.formatters.binary; Class binaryDatanender { Public static void main () { SerialEmployee EMP1 = New SerialEmployee (); SerialEmployee EMP2 = New SerialEmployee (); EMP1.EMPLOYEEID = 1; EMP1.LASTNAME = "blum"; Emp1.firstname = "katie jane"; EMP1.YEARSSERVICE = 12; EMP1.SAlary = 35000.50; EMP2.EMPLOYEEID = 2; Emp2.lastname = "blum"; EMP2.FIRSTNAME = "JESSICA"; EMP2.YEARSSERVICE = 9; EMP2.SAlary = 23700.30; TcpClient Client = New TcpClient ("127.0.0.1", 9050); IFORMATTER FORMATTER = New BinaryFormatter (); NetWorkstream Strm = Client.getStream (); Formatter.Serialize (Strm, EMP1); Formatter.Serialize (STRM, EMP2); Strm.close (); Client.Close (); } } Because the BinaryFormatter and the SOAPFormatter class require a stream object to pass serial data, use a TCP Socket object or a TCPClient object to deliver data, and cannot use UDP directly. 3 Write a receiver Using system; Using system.net; Using system.net.sockets; Using system.runtime.serialization; Using system.runtime.serialization.formatters.binary; Class BinaryDatarcvr { Public static void main () { TCPListener Server = New TCPListener (9050); Server.Start (); TcpClient Client = Server.accePttcpClient (); NetWorkstream Strm = Client.getStream (); IFORMATTER FORMATTER = New BinaryFormatter (); SerialEmployee EMP1 = (serialemployee) Formatter.Deserialize (STRM); Console.writeline ("Emp1.employeeid = {0}", EMP1.EMPLOYEEID; Console.writeline ("Emp1.lastname = {0}", EMP1.LASTNAME); Console.writeline ("Emp1.FirstName = {0}", EMP1.FIRSTNAME); Console.writeline ("Emp1.yearsservice = {0}", EMP1.YEARSERVICE); Console.writeline ("Emp1.salary = {0} / n", EMP1.SALARY); SerialEmployee EMP2 = (serialemployee) formatter.deSerialize (strM); console.writeline ("Emp2.employeID = {0}", EMP2.EMPLOYEEID); Console.writeline ("Emp2.lastname = {0}", EMP2.lastname; Console.writeline ("Emp2.Firstname = {0}", EMP2.FIRSTNAME); Console.writeline ("Emp2.YearsService = {0}", EMP2.YEARSERVICE); Console.writeLine ("Emp2.Salary = {0}", EMP2.SALARY); Strm.close (); Server.stop (); } } Second, the program improvement There is a hypothesis in the previous program: all of the senders are received by the recipient. If the data is lost, the DeSerialize () method will errors. A simple solution is to put serialized data into the MemoryStream object. MemoryStream objects save all serialized data in memory, which can easily get the size of serialized data. When data is transmitted, the data size and data are passed together. Using system; Using system.io; Using system.net; Using system.net.sockets; Using system.runtime.serialization; Using system.Runtime.Serialization.formatters.soap; Class BetterDataSender { Public Void Senddata (NetworkStream Strm, SerialEmployee EMP) { IFORMATTER FORMATTER = New soapFormatter (); MemoryStream MemStrm = new memorystream (); Formatter.Serialize (MemStrM, EMP); BYTE [] DATA = MEMSTRM.GETBUFFER (); INT MEMSIZE = (int) MEMSTRM.LENGTH; Byte [] size = bitconverter.getbytes (Memsize); Strm.write (Size, 0, 4); Strm.write (DATA, 0, MEMSIZE); Strm.flush (); MEMSTRM.CLOSE (); } Public betterDataSender () { SerialEmployee EMP1 = New SerialEmployee (); SerialEmployee EMP2 = New SerialEmployee (); EMP1.EMPLOYEEID = 1; EMP1.LASTNAME = "blum"; Emp1.firstname = "katie jane"; EMP1.YEARSSERVICE = 12; EMP1.SAlary = 35000.50; EMP2.EMPLOYEEID = 2; Emp2.lastname = "blum"; EMP2.FIRSTNAME = "JESSICA"; EMP2.YEARSSERVICE = 9; EMP2.SAlary = 23700.30; TCPCLIENT Client = New TcpClient ("127.0.0.1", 9050); NetworkStream Strm = Client.getStream (); Senddata (Strm, EMP1); Senddata (Strm, EMP2); Strm.close (); Client.Close (); } Public static void main () { BetterDataSnder BDS = New BetterDataSender (); } } The receiving data program is as follows: Using system; Using system.io; Using system.net; Using system.net.sockets; Using system.runtime.serialization; Using system.Runtime.Serialization.formatters.soap; Class BetterDatarcvr { Private SeriaMPloyee Recvdata (NetworkStream Strm) { MemoryStream MemStrm = new memorystream (); Byte [] Data = New Byte [4]; Int Recv = Strm.read (Data, 0, 4); INT size = bitconverter.toint32 (data, 0); INT OFFSET = 0; While (size> 0) { Data = new byte [1024]; RECV = Strm.read (data, 0, size); MemStrm.write (DATA, OFFSET, RECV); OFFSET = RECV; Size - = RECV; } IFORMATTER FORMATTER = New soapFormatter (); MemStrm.Position = 0; SerialEmployee EMP = (serialemployee) formatter.deSerialize (MEMSTRM); MEMSTRM.CLOSE (); Return EMP; } Public BetterDatarcvr () { TCPListener Server = New TCPListener (9050); Server.Start (); TcpClient Client = Server.accePttcpClient (); NetWorkstream Strm = Client.getStream (); SerialEmployee EMP1 = Recvdata (STRM); Console.writeline ("Emp1.employeeid = {0}", EMP1.EMPLOYEEID; Console.writeline ("Emp1.lastname = {0}", EMP1.LASTNAME); Console.writeline ("Emp1.FirstName = {0}", EMP1.FIRSTNAME); Console.writeline ("Emp1.yearsservice = {0}", EMP1.YEARSERVICE); Console.writeline ("Emp1.salary = {0} / n", EMP1.SALARY); SerialEmployee EMP2 = Recvdata (STRM); Console.Writeline ("Emp2.emPloyeeid = {0}", EMP2.EMPLOYEEID; console.writeline ("Emp2.lastName = {0}", EMP2.lastname); Console.writeline ("Emp2.Firstname = {0}", EMP2.FIRSTNAME); Console.writeline ("Emp2.YearsService = {0}", EMP2.YEARSERVICE); Console.writeLine ("Emp2.Salary = {0}", EMP2.SALARY); Strm.close (); Server.stop (); } Public static void main () { Betterdatarcvr BDR = New BetterDatarcvr (); } }