Home / C Sharp / Archive by category 'C# Streams'

C# Streams

Which of the following interfaces should you implement to enable you to run a method after an instance of your class is deserialized?

Which of the following interfaces should you implement to enable you to run a method after an instance of your class is deserialized?
A. IFormatter
B. ISerializable
C. IDeserializationCallback
D. IObjectReference

Implement the IDeserializationCallback interface and the IDeserializationCallback.OnDeserialization method to run code after an object is serialized.


Which of the following attributes should you add to a member to prevent it from being serialized by BinaryFormatter?

Which of the following attributes should you add to a member to prevent it from being serialized by BinaryFormatter?
A. NonSerialized
B. Serializable
C. SerializationException
D. SoapIgnore

The NonSerialized attribute prevents a member from being serialized.


Which of the following attributes should you add to a class to enable it to be serialized?

Which of the following attributes should you add to a class to enable it to be
serialized?
A. ISerializable
B. Serializable
C. SoapInclude
D. OnDeserialization

Classes must have the Serializable attribute to be serialized.


Which of the following are required to serialize an object?

Which of the following are required to serialize an object?
A. An instance of BinaryFormatter or SoapFormatter
B. File permissions to create temporary files
C. Microsoft Internet Information Services (IIS)
D. A stream object

You must call the BinaryFormatter.Serialize method to serialize an object. The BinaryFormatter.Serialize method requires a stream object to act as the destination for the serialization.


Example of OnSerializing and OnDeserialized

To respond to the onserializing or ondeserialized events, the method must accept a StreamingContext object as a parameter, must return void and have the attribute that matches the event you want to intercept.

[Serializable]
class ShoppingCartItem
{
    public Int32 productId;
    public decimal price;
    public Int32 quantity;
    public decimal total;
 
    [OnSerializing]
    void CalculateTotal(StreamingContext sc)
    {
        total = price * quantity;
    }
 
    [OnDeserialized]
    void CheckTotal(StreamingContext sc)
    {
        if (total == 0) { CalculateTotal(sc); }
    }
}

BinaryFormatter serialization events in C#

Serializing – This event is raised just before serialization takes place. Apply the OnSerializing attribute to the method that should run in response to this event.

Serialized – This event is raised just after serialization takes place. Apply the OnSerialized attribute to the method that should run in response to this event.

Deserializing – This event is raised just before deserialization takes place. Apply the OnDeserializing attribute to the method that should run in response to this event.

Deserialized – This event is raised just after deserialization takes place and after IDeserializationCallback.OnDeserialization has been called. You should use IDeserializationCallback. OnDeserialization instead when formatters other than BinaryFormatter might be used. Apply the OnDeserialized attribute to the method that should run in response to this event.


How to implement ISerializable, the serialization constructor, and the GetObjectData method

Implementing ISerializable involves implementing the GetObjectData method and a special constructor that is used when the object is deserialized. The runtime calls GetObjectData during serialization, and the serialization constructor during deserialization.
When the runtime calls GetObjectData during serialization, you are responsible for populating the SerializationInfo object that is provided with the method call. Simply add the variables to be serialized as name/value pairs using the AddValue method, which internally creates SerializationEntry structures to store the information.

[Serializable]
class ShoppingCartItem : ISerializable
{
public Int32 productId;
public decimal price;
public Int32 quantity;
[NonSerialized]
public decimal total;
 
// The standard, non-serialization constructor
public ShoppingCartItem(int _productID, decimal _price, int _quantity)
{
productId = _productID;
price = _price;
quantity = _quantity;
total = price * quantity;
}
 
// The following constructor is for deserialization
protected ShoppingCartItem(SerializationInfo info,StreamingContext context)
{
productId = info.GetInt32("Product ID");
price = info.GetDecimal("Price");
quantity = info.GetInt32("Quantity");
total = price * quantity;
}
 
// The following method is called during serialization
[SecurityPermissionAttribute(SecurityAction.Demand,SerializationFormatter=true)]
public virtual void GetObjectData(SerializationInfo info,StreamingContext context)
{
info.AddValue("Product ID", productId);
info.AddValue("Price", price);
info.AddValue("Quantity", quantity);
}
 
public override string ToString()
{
return productId + ": " + price + " x " + quantity + " = " + total;
}
}

Socket client in C#

 
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Net.Sockets;
 
public class clnt {
 
  public static void Main() {
 
    try {
 
      TcpClient tcpclnt = new TcpClient();
      Console.WriteLine("Attempting to connect to server.");
 
      tcpclnt.Connect("127.0.0.1",8001); 
 
      Console.WriteLine("Connected to server.");
      Console.Write("Enter the string to be transmitted: ");
 
      String str=Console.ReadLine();
      Stream stm = tcpclnt.GetStream();
 
      ASCIIEncoding asen= new ASCIIEncoding();
      byte[] ba=asen.GetBytes(str);
      Console.WriteLine("Transmitting...");
 
      stm.Write(ba,0,ba.Length);
 
      byte[] bb=new byte[100];
      int k=stm.Read(bb,0,100);
 
      Console.Write("Server reply: ");
      for (int i=0;i<k;i++) Console.Write(Convert.ToChar(bb[i]));
      Console.WriteLine("  EOT");
 
      tcpclnt.Close();
    } catch (Exception e) { 
      Console.WriteLine("Error: " + e.StackTrace);
    }
  }
 
}

Socket server in C#

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
 
public class SocketServer {
 
  public static void Main() {
 
    try {
 
      IPAddress ipAd = IPAddress.Parse("127.0.0.1"); 
      TcpListener myList = new TcpListener(ipAd,8001);
 
      myList.Start();
 
      Console.WriteLine("Server ready.");
 
      Socket s = myList.AcceptSocket();
 
      Console.WriteLine("Connection accepted from "+s.RemoteEndPoint);
 
      byte[] b = new byte[1024];
      int k = s.Receive(b);
      Console.Write("Message from client: ");
      for (int i=0;i<k;i++) Console.Write(Convert.ToChar(b[i]));
      Console.WriteLine("  EOT");
 
      ASCIIEncoding asen = new ASCIIEncoding();
      s.Send(asen.GetBytes("The string was recieved by the server."));
 
      s.Close();
      myList.Stop();
 
    } catch (Exception e) {
      Console.WriteLine("Error: " + e.StackTrace);
    }  
  }
 
}

Using a IPEndPoint to connect with a remote host

//Uses a remote end point to establish a socket connection.
   TcpClient tcpClient = new TcpClient();
   IPAddress ipAddress = Dns.Resolve("www.contoso.com").AddressList[0];
   IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 11004);
   try{
   	tcpClient.Connect(ipEndPoint);
   }
   catch (Exception e ) {
              Console.WriteLine(e.ToString());
          }

Creating an instance of the TcpClient class using a local endpoint

 //Creates a TCPClient using a localend point.
           IPAddress ipAddress = Dns.Resolve(Dns.GetHostName()).AddressList[0];
           IPEndPoint ipLocalEndPoint = new IPEndPoint(ipAddress, 11000);
           try{
                    TcpClient tcpClientA = new TcpClient(ipLocalEndPoint);
           }  
           catch (Exception e ) {
                     Console.WriteLine(e.ToString());
             }

TcpClient connection in C# sockets

The following example establishes a TcpClient connection using the host name www.w3mentor.com on port 1100. You use the underlying NetworkStream instance to send and receive simple string statements.

TcpClient tcpClient = new TcpClient();
    try{
        tcpClient.Connect("www.w3mentor.com", 1100);
        NetworkStream networkStream = tcpClient.GetStream();
 
        if(networkStream.CanWrite && networkStream.CanRead){
 
            // Does a simple write.
            Byte[] sendBytes = Encoding.ASCII.GetBytes("Is anybody there");
            networkStream.Write(sendBytes, 0, sendBytes.Length);
 
            // Reads the NetworkStream into a byte buffer.
            byte[] bytes = new byte[tcpClient.ReceiveBufferSize];
            networkStream.Read(bytes, 0, (int) tcpClient.ReceiveBufferSize);
 
           // Returns the data received from the host to the console.
           string returndata = Encoding.ASCII.GetString(bytes);
           Console.WriteLine("This is what the host returned to you: " + returndata);
 
          }
          else if (!networkStream.CanRead){
              Console.WriteLine("You can not write data to this stream");
              tcpClient.Close();
          }
          else if (!networkStream.CanWrite){             
              Console.WriteLine("You can not read data from this stream");
              tcpClient.Close();
          }
       }
       catch (Exception e ) {
                  Console.WriteLine(e.ToString());
       }

MulticastOption in C# sockets

The MulticastOption class sets IP address values when joining or leaving an IP multicast group.

The following examples joins the default IP interface to an IP multicast group. It assumes that groupIP is an IPAddress instance that has been set to the IP multicast group address in the range 224.0.0.0 to 239.255.255.255.

Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp ); 
sock.SetSocketOption(SocketOptionLevel.IP, 
    SocketOptionName.AddMembership, 
    new MulticastOption( groupIP ));

LingerOption in C# sockets

The settings of the LingerOption instance associated with a Socket instance control the length of time that a socket will remain after closing if data remains to be sent.

 LingerOption myOpts = new LingerOption(true,1);
 mySocket.SetSocketOption(SocketOptionLevel.IP,SocketOptionName.Linger,myOpts);

Socket class to send data and receive the response

The Socket class creates a managed version of an Internet transport service. Once the Socket is created, the Socket is bound to a specific endpoint through the Socket.Bind method, and the connection to that endpoint is established through the Socket.Connect method. Data is sent to the Socket using the Socket.Send or Socket.SendTo methods, and data is read from the Socket using the Socket.Receive or Socket.ReceiveFrom methods. After you are done with the Socket, use the Socket.Shutdown method to disable the Socket, and the Socket.Close method to close the Socket.

Example:

public string DoSocketGet(string server) 
 {
    //Sets up variables and a string to write to the server
    Encoding ASCII = Encoding.ASCII;
    string Get = "GET / HTTP/1.1\r\nHost: " + server + 
                 "\r\nConnection: Close\r\n\r\n";
    Byte[] ByteGet = ASCII.GetBytes(Get);
    Byte[] RecvBytes = new Byte[256];
    String strRetPage = null;
 
    // IPAddress and IPEndPoint represent the endpoint that will
    //   receive the request.
    // Get the first IPAddress in the list using DNS.
    IPAddress hostadd = Dns.Resolve(server).AddressList[0];
    IPEndPoint EPhost = new IPEndPoint(hostadd, 80);
 
    //Creates the Socket for sending data over TCP.
    Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
       ProtocolType.Tcp );
 
    // Connects to the host using IPEndPoint.
    s.Connect(EPhost);
    if (!s.Connected)
    {
       strRetPage = "Unable to connect to host";
       return strRetPage;
    }
 
    // Sends the GET text to the host.
    s.Send(ByteGet, ByteGet.Length, SocketFlags.None);
 
    // Receives the page, looping until all bytes are received
    Int32 bytes = s.Receive(RecvBytes, RecvBytes.Length, 0);
    strRetPage = "Default HTML page on " + server + ":\r\n";
    strRetPage = strRetPage + ASCII.GetString(RecvBytes, 0, bytes);
 
    while (bytes > 0)
    {
       bytes = s.Receive(RecvBytes, RecvBytes.Length, SocketFlags.None);
       strRetPage = strRetPage + ASCII.GetString(RecvBytes, 0, bytes);
    }
 
    return strRetPage;
 }

Example of IDeserializationCallback.OnDeserialization implementation

To prevent a data member from being serialized, we would mark it with the [NonSerialized] attribute.

Example:

[NonSerialized] public decimal total;

To enable your class to initialize a nonserialized member automatically, use the IDeserializationCallback interface and then implement IDeserializationCallback.OnDeserialization. Each time your class is deserialized, the runtime calls the IDeserializationCallback.OnDeserialization method after deserialization is complete.

[Serializable]
class ShoppingCartItem : IDeserializationCallback {
    public int productId;
    public decimal price;
    public int quantity;
    [NonSerialized] public decimal total;
    public ShoppingCartItem(int _productID, decimal _price, int _quantity)
    {
        productId = _productID;
        price = _price;
        quantity = _quantity;
        total = price * quantity;
    }
    void IDeserializationCallback.OnDeserialization(Object sender)
    {
        // After deserialization, calculate the total
        total = price * quantity;
    }
}

What is a fixup in C#

A fixup is the process of finalizing an object reference after the referenced object has been deserialized.


How to Deserialize an Object in C#

1. Create a stream object to read the serialized output.
2. Create a BinaryFormatter object.
3. Create a new object to store the deserialized data.
4. Call the BinaryFormatter.Deserialize method to deserialize the object, and cast it to the correct type.

// Open file from which to read the data
FileStream fs = new FileStream("SerializedString.Data", FileMode.Open);
 
// Create a BinaryFormatter object to perform the deserialization
BinaryFormatter bf = new BinaryFormatter();
 
// Create the object to store the deserialized data
string data = "";
 
// Use the BinaryFormatter object to deserialize the data from the file
data = (string)bf.Deserialize(fs);
 
// Close the file
fs.Close();
// Display the deserialized string
Console.WriteLine(data);

How to Serialize an Object in C#

1. Create a stream object to hold the serialized output.
2. Create a BinaryFormatter object (located in System.Runtime.Serialization.Formatters.Binary).
3. Call the BinaryFormatter.Serialize method to serialize the object and output the result to the stream.

string data = "This must be stored in a file.";
 
// Create file to save the data to
FileStream fs = new FileStream("SerializedString.Data", FileMode.Create);
 
// Create a BinaryFormatter object to perform the serialization
BinaryFormatter bf = new BinaryFormatter();
 
// Use the BinaryFormatter object to serialize the data to the file
bf.Serialize(fs, data);
 
// Close the file
fs.Close();

The FileStream object in c# .NET

The FileStream object provides access to the contents of a file, both for reading and writing purposes. It accesses file data at the byte level, and so is not always the best choice for accessing file data. A FileStream instance maintains a position byte index within a file so that you can navigate through the contents of a file. Accessing a file at any point in this way is known as random access.