Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Wednesday, March 02, 2011

a custom serialization test

works pretty fast

using System;
using System.IO;
using System.IO.Compression;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;

namespace serializationtest
{
internal enum SerializedType : ushort
{
ByteArray = 0,
Object = 1,
String = 2,
Datetime = 3,
Bool = 4,
//SByte = 5, //Makes no sense.
Byte = 6,
Short = 7,
UShort = 8,
Int = 9,
UInt = 10,
Long = 11,
ULong = 12,
Float = 13,
Double = 14,

CompressedByteArray = 255,
CompressedObject = 256,
CompressedString = 257,
}

internal class Serializer
{
public static byte[] Serialize(object value, out SerializedType type, uint compressionThreshold)
{
byte[] bytes;
if (value is byte[])
{
bytes = (byte[])value;
type = SerializedType.ByteArray;
if (bytes.Length > compressionThreshold)
{
bytes = compress(bytes);
type = SerializedType.CompressedByteArray;
}
}
else if (value is string)
{
bytes = Encoding.UTF8.GetBytes((string)value);
type = SerializedType.String;
if (bytes.Length > compressionThreshold)
{
bytes = compress(bytes);
type = SerializedType.CompressedString;
}
}
else if (value is DateTime)
{
bytes = BitConverter.GetBytes(((DateTime)value).Ticks);
type = SerializedType.Datetime;
}
else if (value is bool)
{
bytes = new byte[] { (byte)((bool)value ? 1 : 0) };
type = SerializedType.Bool;
}
else if (value is byte)
{
bytes = new byte[] { (byte)value };
type = SerializedType.Byte;
}
else if (value is short)
{
bytes = BitConverter.GetBytes((short)value);
type = SerializedType.Short;
}
else if (value is ushort)
{
bytes = BitConverter.GetBytes((ushort)value);
type = SerializedType.UShort;
}
else if (value is int)
{
bytes = BitConverter.GetBytes((int)value);
type = SerializedType.Int;
}
else if (value is uint)
{
bytes = BitConverter.GetBytes((uint)value);
type = SerializedType.UInt;
}
else if (value is long)
{
bytes = BitConverter.GetBytes((long)value);
type = SerializedType.Long;
}
else if (value is ulong)
{
bytes = BitConverter.GetBytes((ulong)value);
type = SerializedType.ULong;
}
else if (value is float)
{
bytes = BitConverter.GetBytes((float)value);
type = SerializedType.Float;
}
else if (value is double)
{
bytes = BitConverter.GetBytes((double)value);
type = SerializedType.Double;
}
else
{
//Object
using (MemoryStream ms = new MemoryStream())
{
new BinaryFormatter().Serialize(ms, value);
bytes = ms.ToArray();
type = SerializedType.Object;
if (bytes.Length > compressionThreshold)
{
bytes = compress(bytes);
type = SerializedType.CompressedObject;
}
}
}
return bytes;
}

private static byte[] compress(byte[] bytes)
{
using (MemoryStream ms = new MemoryStream())
{
using (DeflateStream gzs = new DeflateStream(ms, CompressionMode.Compress, false))
{
gzs.Write(bytes, 0, bytes.Length);
}
ms.Close();
return ms.ToArray();
}
}

private static byte[] decompress(byte[] bytes)
{
using (MemoryStream ms = new MemoryStream(bytes, false))
{
using (DeflateStream gzs = new DeflateStream(ms, CompressionMode.Decompress, false))
{
using (MemoryStream dest = new MemoryStream())
{
byte[] tmp = new byte[bytes.Length];
int read;
while ((read = gzs.Read(tmp, 0, tmp.Length)) != 0)
{
dest.Write(tmp, 0, read);
}
dest.Close();
return dest.ToArray();
}
}
}
}

public static object DeSerialize(byte[] bytes, SerializedType type)
{
switch (type)
{
case SerializedType.String:
return Encoding.UTF8.GetString(bytes);
case SerializedType.Datetime:
return new DateTime(BitConverter.ToInt64(bytes, 0));
case SerializedType.Bool:
return bytes[0] == 1;
case SerializedType.Byte:
return bytes[0];
case SerializedType.Short:
return BitConverter.ToInt16(bytes, 0);
case SerializedType.UShort:
return BitConverter.ToUInt16(bytes, 0);
case SerializedType.Int:
return BitConverter.ToInt32(bytes, 0);
case SerializedType.UInt:
return BitConverter.ToUInt32(bytes, 0);
case SerializedType.Long:
return BitConverter.ToInt64(bytes, 0);
case SerializedType.ULong:
return BitConverter.ToUInt64(bytes, 0);
case SerializedType.Float:
return BitConverter.ToSingle(bytes, 0);
case SerializedType.Double:
return BitConverter.ToDouble(bytes, 0);
case SerializedType.Object:
using (MemoryStream ms = new MemoryStream(bytes))
{
return new BinaryFormatter().Deserialize(ms);
}
case SerializedType.CompressedByteArray:
return DeSerialize(decompress(bytes), SerializedType.ByteArray);
case SerializedType.CompressedString:
return DeSerialize(decompress(bytes), SerializedType.String);
case SerializedType.CompressedObject:
return DeSerialize(decompress(bytes), SerializedType.Object);
case SerializedType.ByteArray:
default:
return bytes;
}
}
}
}

Sunday, May 02, 2010

Async Socket Server Sample in C#

Networking Samples for .NET v4.0 contains some cool samples.

They also provide an example for an async socket server and client. very cool stuff!


Asynchronous Socket Server Sample
=================================

This sample demonstrates how to use the xxxAsync (xxx = receive, send, connect, etc) methods on the Sytem.Net.Sockets.Socket
class by implementing an echo server (ie. The server sends all the data read from a client back to the client).
The echo server implemented in this sample handles multiple clients simultaneously (up to a maximum specified as a command line argument)
and highlights some of the key elements of the event-based asynchronous socket methods.
The sample illustrates creating a pool of reusable data buffers and SocketAsyncEventArgs context objects as a method to
increase server performance.

The sample is intended for educational purposes and should not be used directly in production applications.



Sample Language Implementations
===============================
This sample is available in the following language implementations:
C#

Prerequisites
=============
This sample requires the .NET Framework v4.0



Building the Sample
===================
To build the sample using Visual Studio (preferred method):

1. Double-click the AsyncSocketServer.sln file to open the socket server sample in Visual Studio.

2. Using the menu, click Build > Build Solution.


To build the sample using the command prompt:

1. Open the Command Prompt window and navigate to the directory containing the socket server sample.

2. Type msbuild AsyncSocketServer.sln.


Running the Sample
==================
The socket server requires four command line parameters.


Usage:

AsyncSocketServer.exe <#connections>





# Connections: The maximum number of connections the server will accept simultaneously.

Receive Size in Bytes: The buffer size used by the server for each receive operation.

Address family: The address family of the socket the server will use to listen for incoming connections. Supported values are ‘ipv4’ and ‘ipv6’.

Local Port Number: The port to which the server will bind.



Example:

AsyncSocketServer.exe 500 1024 ipv4 8000




The client part:



using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;

//Implements a sample socket client to connect to the server implmented in the AsyncSocketServer project
//Usage: AsyncSocketClient.exe <destination IP address> <destination port number>

//Destination IP address: The IP Address of the server to connect to
//Destination Port Number: The port number to connect to

namespace AsyncSocketClient
{
class Program
{
static ManualResetEvent clientDone = new ManualResetEvent(false);

static void Main(string[] args)
{
IPAddress destinationAddr = null; // IP Address of server to connect to
int destinationPort = 0; // Port number of server
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();


if (args.Length != 2)
{
Console.WriteLine("Usage: AsyncSocketClient.exe <destination IP address> <destination port number>");
}
try
{
destinationAddr = IPAddress.Parse(args[0]);
destinationPort = int.Parse(args[1]);
if (destinationPort <= 0){
throw new ArgumentException("Destination port number provided cannot be less than or equal to 0");
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine("Usage: AsyncSocketClient.exe <destination IP address> <destination port number>");
}

// Create a socket and connect to the server
Socket sock = new Socket(destinationAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(SocketEventArg_Completed);
socketEventArg.RemoteEndPoint = new IPEndPoint(destinationAddr, destinationPort);
socketEventArg.UserToken = sock;
sock.ConnectAsync(socketEventArg);
clientDone.WaitOne();
}

/// <summary>
/// A single callback is used for all socket operations. This method forwards execution on to the correct handler
/// based on the type of completed operation
/// </summary>
static void SocketEventArg_Completed(object sender, SocketAsyncEventArgs e)
{
switch (e.LastOperation)
{
case SocketAsyncOperation.Connect:
ProcessConnect(e);
break;
case SocketAsyncOperation.Receive:
ProcessReceive(e);
break;
case SocketAsyncOperation.Send:
ProcessSend(e);
break;
default:
throw new Exception("Invalid operation completed");
}
}

/// <summary>
/// Called when a ConnectAsync operation completes
/// </summary>
private static void ProcessConnect(SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
Console.WriteLine("Successfully connected to the server");

// Send 'Hello World' to the server
byte[] buffer = Encoding.UTF8.GetBytes("Hello World");
e.SetBuffer(buffer, 0, buffer.Length);
Socket sock = e.UserToken as Socket;
bool willRaiseEvent = sock.SendAsync(e);
if (!willRaiseEvent)
{
ProcessSend(e);
}
}
else
{
throw new SocketException((int)e.SocketError);
}
}

/// <summary>
/// Called when a ReceiveAsync operation completes
/// </summary>
private static void ProcessReceive(SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
Console.WriteLine("Received from server: {0}", Encoding.UTF8.GetString(e.Buffer, 0, e.BytesTransferred));

// Data has now been sent and received from the server. Disconnect from the server
Socket sock = e.UserToken as Socket;
sock.Shutdown(SocketShutdown.Send);
sock.Close();
clientDone.Set();
}
else
{
throw new SocketException((int)e.SocketError);
}
}


/// <summary>
/// Called when a SendAsync operation completes
/// </summary>
private static void ProcessSend(SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
Console.WriteLine("Sent 'Hello World' to the server");

//Read data sent from the server
Socket sock = e.UserToken as Socket;
bool willRaiseEvent = sock.ReceiveAsync(e);
if (!willRaiseEvent)
{
ProcessReceive(e);
}
}
else
{
throw new SocketException((int)e.SocketError);
}
}
}
}



The server classes:


using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;

namespace AsyncSocketSample
{

/// <summary>
/// This class is designed for use as the object to be assigned to the SocketAsyncEventArgs.UserToken property.
/// </summary>
class AsyncUserToken
{
Socket m_socket;

public AsyncUserToken() : this(null) { }

public AsyncUserToken(Socket socket)
{
m_socket = socket;
}

public Socket Socket
{
get { return m_socket; }
set { m_socket = value; }
}

}
}



using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;

namespace AsyncSocketSample
{
/// <summary>
/// This class creates a single large buffer which can be divided up and assigned to SocketAsyncEventArgs objects for use
/// with each socket I/O operation. This enables bufffers to be easily reused and gaurds against fragmenting heap memory.
///
/// The operations exposed on the BufferManager class are not thread safe.
/// </summary>
class BufferManager
{
int m_numBytes; // the total number of bytes controlled by the buffer pool
byte[] m_buffer; // the underlying byte array maintained by the Buffer Manager
Stack<int> m_freeIndexPool; //
int m_currentIndex;
int m_bufferSize;

public BufferManager(int totalBytes, int bufferSize)
{
m_numBytes = totalBytes;
m_currentIndex = 0;
m_bufferSize = bufferSize;
m_freeIndexPool = new Stack<int>();
}

/// <summary>
/// Allocates buffer space used by the buffer pool
/// </summary>
public void InitBuffer()
{
// create one big large buffer and divide that out to each SocketAsyncEventArg object
m_buffer = new byte[m_numBytes];
}

/// <summary>
/// Assigns a buffer from the buffer pool to the specified SocketAsyncEventArgs object
/// </summary>
/// <returns>true if the buffer was successfully set, else false</returns>
public bool SetBuffer(SocketAsyncEventArgs args)
{

if (m_freeIndexPool.Count > 0)
{
args.SetBuffer(m_buffer, m_freeIndexPool.Pop(), m_bufferSize);
}
else
{
if ((m_numBytes - m_bufferSize) < m_currentIndex)
{
return false;
}
args.SetBuffer(m_buffer, m_currentIndex, m_bufferSize);
m_currentIndex += m_bufferSize;
}
return true;
}

/// <summary>
/// Removes the buffer from a SocketAsyncEventArg object. This frees the buffer back to the
/// buffer pool
/// </summary>
public void FreeBuffer(SocketAsyncEventArgs args)
{
m_freeIndexPool.Push(args.Offset);
args.SetBuffer(null, 0, 0);
}


}
}



using System;
using System.Collections.Generic;
using System.Text;
using System.Net;


//This project implements an echo socket server.
//The socket server requires four command line parameters:
//Usage: AsyncSocketServer.exe <#connections> <Receive Size In Bytes> <address family: ipv4 | ipv6> <Local Port Number>

//# Connections: The maximum number of connections the server will accept simultaneously.
//Receive Size in Bytes: The buffer size used by the server for each receive operation.
//Address family: The address family of the socket the server will use to listen for incoming connections. Supported values are ‘ipv4’ and ‘ipv6’.
//Local Port Number: The port the server will bind to.

//Example: AsyncSocketServer.exe 500 1024 ipv4 8000



namespace AsyncSocketSample
{
class Program
{
static void Main(string[] args)
{
int numConnections;
int receiveSize;
IPEndPoint localEndPoint;
int port;

// parse command line parameters
//format: #connections, receive size per connection, address family, port num
if (args.Length < 4)
{
Console.WriteLine("Usage: AsyncSocketServer.exe <#connections> <receiveSizeInBytes> <address family: ipv4 | ipv6> <Local Port Number>");
return;
}

try
{
numConnections = int.Parse(args[0]);
receiveSize = int.Parse(args[1]);
string addressFamily = args[2].ToLower();
port = int.Parse(args[3]);


if (numConnections <= 0)
{
throw new ArgumentException("The number of connections specified must be greater than 0");
}
if (receiveSize <= 0)
{
throw new ArgumentException("The receive size specified must be greater than 0");
}
if (port <= 0)
{
throw new ArgumentException("The port specified must be greater than 0");
}

// This sample supports two address family types: ipv4 and ipv6
if (addressFamily.Equals("ipv4"))
{
localEndPoint = new IPEndPoint(IPAddress.Any, port);
}
else if (addressFamily.Equals("ipv6"))
{
localEndPoint = new IPEndPoint(IPAddress.IPv6Any, port);
}
else
{
throw new ArgumentException("Invalid address family specified");
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine("Usage: AsyncSocketServer.exe <#connections> <receiveSizeInBytes> <address family: ipv4 | ipv6> <Local Port Number>");
return;
}

Console.WriteLine("Press any key to start the server ...");
Console.ReadKey();

// Start the server listening for incoming connection requests
Server server = new Server(numConnections, receiveSize);
server.Init();
server.Start(localEndPoint);


}
}
}





using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;


namespace AsyncSocketSample
{
/// <summary>
/// Implements the connection logic for the socket server. After accepting a connection, all data read
/// from the client is sent back to the client. The read and echo back to the client pattern is continued
/// until the client disconnects.
/// </summary>
class Server
{
private int m_numConnections; // the maximum number of connections the sample is designed to handle simultaneously
private int m_receiveBufferSize;// buffer size to use for each socket I/O operation
BufferManager m_bufferManager; // represents a large reusable set of buffers for all socket operations
const int opsToPreAlloc = 2; // read, write (don't alloc buffer space for accepts)
Socket listenSocket; // the socket used to listen for incoming connection requests
// pool of reusable SocketAsyncEventArgs objects for write, read and accept socket operations
SocketAsyncEventArgsPool m_readWritePool;
int m_totalBytesRead; // counter of the total # bytes received by the server
int m_numConnectedSockets; // the total number of clients connected to the server
Semaphore m_maxNumberAcceptedClients;

/// <summary>
/// Create an uninitialized server instance. To start the server listening for connection requests
/// call the Init method followed by Start method
/// </summary>
/// <param name="numConnections">the maximum number of connections the sample is designed to handle simultaneously</param>
/// <param name="receiveBufferSize">buffer size to use for each socket I/O operation</param>
public Server(int numConnections, int receiveBufferSize)
{
m_totalBytesRead = 0;
m_numConnectedSockets = 0;
m_numConnections = numConnections;
m_receiveBufferSize = receiveBufferSize;
// allocate buffers such that the maximum number of sockets can have one outstanding read and
//write posted to the socket simultaneously
m_bufferManager = new BufferManager(receiveBufferSize * numConnections * opsToPreAlloc,
receiveBufferSize);

m_readWritePool = new SocketAsyncEventArgsPool(numConnections);
m_maxNumberAcceptedClients = new Semaphore(numConnections, numConnections);
}

/// <summary>
/// Initializes the server by preallocating reusable buffers and context objects. These objects do not
/// need to be preallocated or reused, by is done this way to illustrate how the API can easily be used
/// to create reusable objects to increase server performance.
/// </summary>
public void Init()
{
// Allocates one large byte buffer which all I/O operations use a piece of. This gaurds
// against memory fragmentation
m_bufferManager.InitBuffer();

// preallocate pool of SocketAsyncEventArgs objects
SocketAsyncEventArgs readWriteEventArg;

for (int i = 0; i < m_numConnections; i++)
{
//Pre-allocate a set of reusable SocketAsyncEventArgs
readWriteEventArg = new SocketAsyncEventArgs();
readWriteEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed);
readWriteEventArg.UserToken = new AsyncUserToken();

// assign a byte buffer from the buffer pool to the SocketAsyncEventArg object
m_bufferManager.SetBuffer(readWriteEventArg);

// add SocketAsyncEventArg to the pool
m_readWritePool.Push(readWriteEventArg);
}

}

/// <summary>
/// Starts the server such that it is listening for incoming connection requests.
/// </summary>
/// <param name="localEndPoint">The endpoint which the server will listening for conenction requests on</param>
public void Start(IPEndPoint localEndPoint)
{
// create the socket which listens for incoming connections
listenSocket = new Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
listenSocket.Bind(localEndPoint);
// start the server with a listen backlog of 100 connections
listenSocket.Listen(100);

// post accepts on the listening socket
StartAccept(null);

//Console.WriteLine("{0} connected sockets with one outstanding receive posted to each....press any key", m_outstandingReadCount);
Console.WriteLine("Press any key to terminate the server process....");
Console.ReadKey();
}


/// <summary>
/// Begins an operation to accept a connection request from the client
/// </summary>
/// <param name="acceptEventArg">The context object to use when issuing the accept operation on the
/// server's listening socket</param>
public void StartAccept(SocketAsyncEventArgs acceptEventArg)
{
if (acceptEventArg == null)
{
acceptEventArg = new SocketAsyncEventArgs();
acceptEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(AcceptEventArg_Completed);
}
else
{
// socket must be cleared since the context object is being reused
acceptEventArg.AcceptSocket = null;
}

m_maxNumberAcceptedClients.WaitOne();
bool willRaiseEvent = listenSocket.AcceptAsync(acceptEventArg);
if (!willRaiseEvent)
{
ProcessAccept(acceptEventArg);
}
}

/// <summary>
/// This method is the callback method associated with Socket.AcceptAsync operations and is invoked
/// when an accept operation is complete
/// </summary>
void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs e)
{
ProcessAccept(e);
}

private void ProcessAccept(SocketAsyncEventArgs e)
{
Interlocked.Increment(ref m_numConnectedSockets);
Console.WriteLine("Client connection accepted. There are {0} clients connected to the server",
m_numConnectedSockets);

// Get the socket for the accepted client connection and put it into the
//ReadEventArg object user token
SocketAsyncEventArgs readEventArgs = m_readWritePool.Pop();
((AsyncUserToken)readEventArgs.UserToken).Socket = e.AcceptSocket;

// As soon as the client is connected, post a receive to the connection
bool willRaiseEvent = e.AcceptSocket.ReceiveAsync(readEventArgs);
if(!willRaiseEvent){
ProcessReceive(readEventArgs);
}

// Accept the next connection request
StartAccept(e);
}

/// <summary>
/// This method is called whenever a receive or send opreation is completed on a socket
/// </summary>
/// <param name="e">SocketAsyncEventArg associated with the completed receive operation</param>
void IO_Completed(object sender, SocketAsyncEventArgs e)
{
// determine which type of operation just completed and call the associated handler
switch (e.LastOperation)
{
case SocketAsyncOperation.Receive:
ProcessReceive(e);
break;
case SocketAsyncOperation.Send:
ProcessSend(e);
break;
default:
throw new ArgumentException("The last operation completed on the socket was not a receive or send");
}

}

/// <summary>
/// This method is invoked when an asycnhronous receive operation completes. If the
/// remote host closed the connection, then the socket is closed. If data was received then
/// the data is echoed back to the client.
/// </summary>
private void ProcessReceive(SocketAsyncEventArgs e)
{
// check if the remote host closed the connection
AsyncUserToken token = (AsyncUserToken)e.UserToken;
if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
{
//increment the count of the total bytes receive by the server
Interlocked.Add(ref m_totalBytesRead, e.BytesTransferred);
Console.WriteLine("The server has read a total of {0} bytes", m_totalBytesRead);

//echo the data received back to the client
bool willRaiseEvent = token.Socket.SendAsync(e);
if (!willRaiseEvent)
{
ProcessSend(e);
}

}
else
{
CloseClientSocket(e);
}
}

/// <summary>
/// This method is invoked when an asynchronous send operation completes. The method issues another receive
/// on the socket to read any additional data sent from the client
/// </summary>
/// <param name="e"></param>
private void ProcessSend(SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
// done echoing data back to the client
AsyncUserToken token = (AsyncUserToken)e.UserToken;
// read the next block of data send from the client
bool willRaiseEvent = token.Socket.ReceiveAsync(e);
if (!willRaiseEvent)
{
ProcessReceive(e);
}
}
else
{
CloseClientSocket(e);
}
}

private void CloseClientSocket(SocketAsyncEventArgs e)
{
AsyncUserToken token = e.UserToken as AsyncUserToken;

// close the socket associated with the client
try
{
token.Socket.Shutdown(SocketShutdown.Send);
}
// throws if client process has already closed
catch (Exception) { }
token.Socket.Close();

// decrement the counter keeping track of the total number of clients connected to the server
Interlocked.Decrement(ref m_numConnectedSockets);
m_maxNumberAcceptedClients.Release();
Console.WriteLine("A client has been disconnected from the server. There are {0} clients connected to the server", m_numConnectedSockets);

// Free the SocketAsyncEventArg so they can be reused by another client
m_readWritePool.Push(e);
}

}
}



using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;

namespace AsyncSocketSample
{
/// <summary>
/// Represents a collection of resusable SocketAsyncEventArgs objects.
/// </summary>
class SocketAsyncEventArgsPool
{
Stack<SocketAsyncEventArgs> m_pool;

/// <summary>
/// Initializes the object pool to the specified size
/// </summary>
/// <param name="capacity">The maximum number of SocketAsyncEventArgs objects the pool can hold</param>
public SocketAsyncEventArgsPool(int capacity)
{
m_pool = new Stack<SocketAsyncEventArgs>(capacity);
}

/// <summary>
/// Add a SocketAsyncEventArg instance to the pool
/// </summary>
/// <param name="item">The SocketAsyncEventArgs instance to add to the pool</param>
public void Push(SocketAsyncEventArgs item)
{
if (item == null) { throw new ArgumentNullException("Items added to a SocketAsyncEventArgsPool cannot be null"); }
lock (m_pool)
{
m_pool.Push(item);
}
}

/// <summary>
/// Removes a SocketAsyncEventArgs instance from the pool
/// </summary>
/// <returns>The object removed from the pool</returns>
public SocketAsyncEventArgs Pop()
{
lock (m_pool)
{
return m_pool.Pop();
}
}

/// <summary>
/// The number of SocketAsyncEventArgs instances in the pool
/// </summary>
public int Count
{
get { return m_pool.Count; }
}

}
}

IPv6 Client Code in C#

Pretty cool and short sample how to make a IPv6 client in C#.

Additional networking samples with .net 4.0 can be found here.

The server code sample can be found here.


//---------------------------------------------------------------------
// This file is part of the Microsoft .NET Framework SDK Code Samples.
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//This source code is intended only as a supplement to Microsoft
//Development Tools and/or on-line documentation. See these other
//materials for detailed information regarding Microsoft code samples.
//
//THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
//KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//PARTICULAR PURPOSE.
//---------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;

namespace Microsoft.Samples.IPv6Sockets
{
static class IPv6Client
{
static void Main(string[] args)
{
if (args.Length < 1) {
DisplayUsage();
return;
}

string serverDnsName = args[0];
try
{
IPHostEntry resolvedServer = Dns.GetHostEntry(serverDnsName);
for (int i = 0; i < resolvedServer.AddressList.Length; i++)
{
IPAddress address = resolvedServer.AddressList[i];
IPEndPoint serverEndPoint = new IPEndPoint(address, 5150);
Socket tcpSocket =
new Socket(
address.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp);
try
{
tcpSocket.Connect(serverEndPoint);
StreamWriter writer = null;
StreamReader reader = null;
try
{
NetworkStream networkStream =
new NetworkStream(tcpSocket);
writer = new StreamWriter(networkStream);
string clientMessage = "Hi there!";
writer.WriteLine(clientMessage);
writer.Flush();
Console.WriteLine(
"Client sent message: {0}", clientMessage);

reader = new StreamReader(networkStream);
string serverMessage = reader.ReadLine();
Console.WriteLine(
"Client received message: {0}", serverMessage);
}
catch (SocketException ex)
{
Console.WriteLine(
"Message exchange failed: {0}", ex.Message);
}
catch (IOException ex)
{
Console.WriteLine(
"Message exchange failed: {0}", ex.Message);
}
finally
{
if (reader != null)
reader.Close();
if (writer != null)
writer.Close();
}
break;
}
catch (SocketException)
{
if (tcpSocket != null)
tcpSocket.Close();
if (i == resolvedServer.AddressList.Length - 1)
Console.WriteLine(
"Failed to connect to the server.");
}
}

}
catch (SocketException ex)
{
Console.WriteLine(
"Could not resolve server DNS name: {0}", ex.Message);
}
}

private static void DisplayUsage()
{
Console.WriteLine("IPv6Client server_name");
}
}
}

IPv6 Server Code in C#

Pretty cool and short sample how to make a IPv6 server in C#.

Additional networking samples with .net 4.0 can be found here.

The client code sample can be found here.



//---------------------------------------------------------------------
// This file is part of the Microsoft .NET Framework SDK Code Samples.
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//This source code is intended only as a supplement to Microsoft
//Development Tools and/or on-line documentation. See these other
//materials for detailed information regarding Microsoft code samples.
//
//THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
//KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//PARTICULAR PURPOSE.
//---------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;

namespace Microsoft.Samples.IPv6Sockets
{
static class IPv6Server
{
static void Main()
{
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.IPv6Any, 5150);
Socket serverSocket =
new Socket(
AddressFamily.InterNetworkV6,
SocketType.Stream,
ProtocolType.Tcp);
try
{
serverSocket.Bind(localEndPoint);
serverSocket.Listen(int.MaxValue);
Console.WriteLine("Server started.");
Console.WriteLine("Listening on " + localEndPoint.Address.ToString());

while (true)
{
try
{
Socket clientSocket = serverSocket.Accept();
Console.WriteLine(
"Accepted connection from: {0}",
clientSocket.RemoteEndPoint.ToString());

StreamReader reader = null;
StreamWriter writer = null;
try
{
NetworkStream networkStream =
new NetworkStream(clientSocket);
reader = new StreamReader(networkStream);
string clientMessage = reader.ReadLine();
Console.WriteLine(
"Server received message: {0}", clientMessage);

writer = new StreamWriter(networkStream);
string serverMessage = "Hello!";
writer.WriteLine(serverMessage);
writer.Flush();
Console.WriteLine(
"Server sent message: {0}", serverMessage);
}
catch (SocketException ex)
{
Console.WriteLine(
"Message exchange failed: {0}", ex.Message);
}
finally
{
if (reader != null)
reader.Close();
if (writer != null)
writer.Close();
}
}
catch (SocketException ex)
{
Console.WriteLine(
"Server could not accept connection: {0}",
ex.Message);
}
}
}
catch (SocketException ex)
{
Console.WriteLine("Failed to start server: {0}", ex.Message);
}
finally
{
if (serverSocket != null)
serverSocket.Close();
}
}
}
}

Sockets in C#: How to make a HEAD request

this sample have been taken from: http://stackoverflow.com/questions/523930/sockets-in-c-how-to-get-the-response-stream and only one single line needed to be adapted to make a HTTP HEAD request instead of a get



using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.IO.Compression;

namespace HttpUsingSockets
{
public class Program2
{
private static readonly Encoding DefaultEncoding = Encoding.ASCII;
private static readonly byte[] LineTerminator = new byte[] { 13, 10 };

public static void Main2()
{
var host = "stackoverflow.com";
var url = "/questions/523930/sockets-in-c-how-to-get-the-response-stream";

IPHostEntry ipAddress = Dns.GetHostEntry(host);
var ip = new IPEndPoint(ipAddress.AddressList[0], 80);
using (var socket = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
{
socket.Connect(ip);
using (var n = new NetworkStream(socket))
{
// SendRequest(n, new[] { "GET " + url + " HTTP/1.1", "Host: " + host, "Connection: Close", "Accept-Encoding: gzip" });
SendRequest(n, new[] { "HEAD " + url + " HTTP/1.1", "Host: " + host, "Connection: Close", "Accept-Encoding: gzip" });

var headers = new Dictionary<string, string>();
while (true)
{
var line = ReadLine(n);
if (line.Length == 0)
{
break;
}
int index = line.IndexOf(':');
headers.Add(line.Substring(0, index), line.Substring(index + 2));
}

Console.WriteLine("Headers: ");

foreach (string key in headers.Keys)
{
Console.WriteLine("{0}: {1} ", key, headers[key]);
}

string contentEncoding;
if (headers.TryGetValue("Content-Encoding", out contentEncoding))
{
Stream responseStream = n;
if (contentEncoding.Equals("gzip"))
{
responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
}
else if (contentEncoding.Equals("deflate"))
{
responseStream = new DeflateStream(responseStream, CompressionMode.Decompress);
}

var memStream = new MemoryStream();

var respBuffer = new byte[4096];
try
{
int bytesRead = responseStream.Read(respBuffer, 0, respBuffer.Length);
while (bytesRead > 0)
{
memStream.Write(respBuffer, 0, bytesRead);
bytesRead = responseStream.Read(respBuffer, 0, respBuffer.Length);
}
}
finally
{
responseStream.Close();
}

var body = DefaultEncoding.GetString(memStream.ToArray());
Console.WriteLine(body);
}
else
{
while (true)
{
var line = ReadLine(n);
if (line == null)
{
break;
}
Console.WriteLine(line);
}
}
}
}
}

static void SendRequest(Stream stream, IEnumerable<string> request)
{
foreach (var r in request)
{
var data = DefaultEncoding.GetBytes(r);
stream.Write(data, 0, data.Length);
stream.Write(LineTerminator, 0, 2);
}
stream.Write(LineTerminator, 0, 2);
// Eat response
var response = ReadLine(stream);
}

static string ReadLine(Stream stream)
{
var lineBuffer = new List<byte>();
while (true)
{
int b = stream.ReadByte();
if (b == -1)
{
return null;
}
if (b == 10)
{
break;
}
if (b != 13)
{
lineBuffer.Add((byte)b);
}
}
return DefaultEncoding.GetString(lineBuffer.ToArray());
}
}
}

All you need for TCP / HTTP IP Tunneling

Definition of tunneling (port forwarding) is the transmission of data intended for use only within a private or corporate network through a public network. This way data gets routed to a different destination. Usually it's nothing else the to encapsulate the private network data and protocol information to a public network. Tunneling simple allows Internet users (from a public network) to send and receive data from your home network (or any other private network).

One approach to tunneling is Point-To-Point tunneling protocol (PPTP) which has been developed by Microsoft and many other companies. The PPTP makes it possible to receive access to a private network (virtual private network - [VPN]) over your Internet service provider or any other online service.

Normally data will be encrypted and decrypted upon transfers. In cases where a high level of security is necessary the highest level is given by VPN iteself.

One some other researches I done i found a project who can manage that. The full source code project can be found below the following repository.


Update: Ian van Reenen request [comments] me to remove the code from this post. I did not fully understand why he means illegal but he ask for so i'll respekt it.
the code were public available in various source repositories withou any license terms - is ther a default license term when the owner does not add one? i don't know it.

anyway: soon I post a different solution for tcp tunneling - in the meanwhile you find a solution from mentalis.org over here.

the project descirption sounds good:

The proxy project is an implementation of an HTTP, FTP and SOCKS proxy server and PortMap server. It is very configurable and, as far as we know, very stable and secure. It is an excellent tool for .NET programmers who want to install a home network. All the classes are fully documented and can be used in other projects that require similar functionality. The project does not require you to have Visual Studio .NET.

Only return first IP which is IP4


// This is separate as we need to encapsulate more than FCL offers us
// It is here so it is reusable by all
// It only returns the first IP, that is by design. If you want the full
// list, use the FCL methods directly.
protected IPAddress ResolveAddress(string aAddress) {
IPHostEntry xIP = Dns.GetHostEntry(aAddress);
// Some host names (ie localhost) can return mult entries
// For now we want the first IP4 one, which is not always in [0]
return xIP.AddressList.First(x => x.AddressFamily == AddressFamily.InterNetwork);
}

The ISO 8601 format string


/// <summary>
/// The ISO 8601 format string.
/// </summary>

private const string Iso8601Format = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'";

//SortableDateTimePattern (ISO 8601)
public static string ToIso8601(DateTime value)
{
return value.ToUniversalTime().ToString(Iso8601Format, CultureInfo.InvariantCulture);
}

public static DateTime ParseIso8601(string value)
{
return DateTime.ParseExact(value,
Iso8601Format, CultureInfo.InvariantCulture,
DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);
}

Kayak is a lightweight HTTP server & framework

The Author say:
It's written in C#, it has been carefully designed to be true to the protocol it implements, get out of your way, and not tell you how to live. It is easy to integrate into a variety of applications, and is an excellent choice for creating interactive websites and web APIs. Whether your coming from ASP.NET, PHP, Django, or elsewhere, you’ll find Kayak to be refreshingly simple to use.

http://kayakhttp.com/

especially i liked the extensions to read / write http

using System;
using System.IO;
using System.Text;

namespace Kayak
{
struct HttpRequestLine
{
public string Verb;
public string RequestUri;
public string HttpVersion;
}

struct HttpStatusLine
{
public string HttpVersion;
public int StatusCode;
public string ReasonPhrase;
}

/// <summary>
/// A collection of extension methods to help speak HTTP.
/// </summary>
static class HttpExtensions
{
/// <summary>
/// Parses the first line of an incoming HTTP request.
/// </summary>
public static HttpRequestLine ReadHttpRequestLine(this Stream stream)
{
string statusLine = stream.ReadLine(Encoding.ASCII, 1024 * 4);

if (string.IsNullOrEmpty(statusLine))
throw new Exception("Could not parse request status.");

int firstSpace = statusLine.IndexOf(' ');
int lastSpace = statusLine.LastIndexOf(' ');

if (firstSpace == -1 || lastSpace == -1)
throw new Exception("Could not parse request status.");

var requestLine = new HttpRequestLine();
requestLine.Verb = statusLine.Substring(0, firstSpace);

bool hasVersion = lastSpace != firstSpace;

if (hasVersion)
requestLine.HttpVersion = statusLine.Substring(lastSpace + 1);
else
requestLine.HttpVersion = "HTTP/1.0";

requestLine.RequestUri = hasVersion
? statusLine.Substring(firstSpace + 1, lastSpace - firstSpace - 1)
: statusLine.Substring(firstSpace + 1);

return requestLine;
}

/// <summary>
/// Parses a list of HTTP request headers, terminated by an empty line.
/// </summary>
public static NameValueDictionary ReadHttpHeaders(this Stream stream)
{
var headers = new NameValueDictionary();
string line = null;

while (!string.IsNullOrEmpty(line = stream.ReadLine(Encoding.ASCII, 1024 * 4)))
{
int colon = line.IndexOf(':');
headers.Add(line.Substring(0, colon), line.Substring(colon + 1).Trim());
}

headers.BecomeReadOnly();

return headers;
}

public static void WriteHttpStatusLine(this Stream stream,
HttpStatusLine statusLine)
{
// e.g. HTTP/1.0 200 OK
string line = string.Format("{0} {1} {2}\r\n", statusLine.HttpVersion, statusLine.StatusCode, statusLine.ReasonPhrase);
byte[] statusBytes = Encoding.ASCII.GetBytes(line);
stream.Write(statusBytes, 0, statusBytes.Length);
}

public static void WriteHttpHeaders(this Stream stream, NameValueDictionary headers)
{
using (StreamWriter writer = new StreamWriter(stream, Encoding.ASCII))
{
writer.NewLine = "\r\n";

foreach (NameValuePair pair in headers)
foreach (string value in pair.Values)
writer.WriteLine("{0}: {1}", pair.Name, value);

writer.WriteLine();
writer.Flush();
}
}
}
}



some cool cookie extensions are also available:

using System.Text;
using System.Web;

namespace Kayak
{
static class CookieExtensions
{
public static HttpCookieCollection ParseAsCookieHeader(this string cookies)
{
var coll = new HttpCookieCollection();

if (!string.IsNullOrEmpty(cookies))
foreach (string cookie in cookies.Split(';'))
{
int index = cookie.IndexOf('=');
if (index >= 0)
coll.Add(new HttpCookie(cookie.Substring(0, index).Trim(), cookie.Substring(index + 1)));
}

return coll;
}

public static void CopyToHeaderDictionary(this HttpCookieCollection cookies,
NameValueDictionary headers)
{
foreach (string name in cookies)
headers.Add("Set-Cookie", cookies[name].ToSetCookieHeader());
}

public static string ToSetCookieHeader(this HttpCookie cookie)
{
var sb = new StringBuilder()
.Append(cookie.Name)
.Append('=')
.Append(cookie.Value);

if (cookie.Domain != null)
sb.Append("; domain=").Append(cookie.Domain);

if (cookie.Path != null)
sb.Append("; path=").Append(cookie.Path);

sb.Append("; expires=").Append(cookie.Expires.ToUniversalTime().ToString("r"));

if (cookie.Secure)
sb.Append("; secure");

if (cookie.HttpOnly)
sb.Append("; HttpOnly");

return sb.ToString();
}
}
}

Saturday, May 01, 2010

Using Asynchronous Sockets

the following have been taken from this url: http://codeidol.com/csharp/csharp-network/Asynchronous-Sockets/Using-Asynchronous-Sockets

an additional article is this one: http://www.codeguru.com/csharp/csharp/cs_misc/sampleprograms/print.php/c7695/%5C%5Cwww.vt.edu

The Socket object contains methods that utilize the AsyncCallback class to call completion methods when the network functions are finished. This allows the application to continue processing other events while waiting for network operations to complete their work.

The Socket asynchronous methods split common network programming functions into two pieces:

A Begin method that starts the network function and registers the AsyncCallback method

An End method that completes the function when the AsyncCallback method is called

Table 8.1 shows the asynchronous methods that are available to use with Socket objects. Each Begin method has an associated End method to complete the function.

Table 8.1: .Net asynchronous Socket methods Requests Started By…
Description of Request
Requests Ended BY…

BeginAccept()
To accept an incoming connection
EndAccept()

BeginConnect()
To connect to a remote host
EndConnect()

BeginReceive()
To retrieve data from a socket
EndReceive()

BeginReceiveFrom()
To retrieve data from a specific remote host
EndReceiveFrom()

BeginSend()
To send data from a socket
EndSend()

BeginSendTo()
To send data to a specific remote host
EndSendTo()

Note Notice that these methods apply only to Socket objects. In .NET Framework release 1, the TcpClient, TcpListener, and UdpClient classes do not include asynchronous methods.


In this section, we’ll walk through the process of using each of the asynchronous Socket methods to process network functions. Then we’ll look at a couple of sample programs that put it all together.

Establishing the Connection
The method used to establish a connection with a remote host depends on whether the program is acting as a server (waiting for clients to connect to it) or a client (attempting to connect to a remote server). For servers, the BeginAccept() method should be used; for clients, the BeginConnect() method is used.

The BeginAccept() and EndAccept() Methods
To accept an incoming connection attempt from a remote client, you must use the BeginAccept() method. Its format is as follows:

IAsyncResult BeginAccept(AsyncCallback callback, object state)
The BeginAccept() method takes two parameters: the name of the AsyncCallback method used to complete the function, and a generic state object that can pass information between the asynchronous methods.

This is how the BeginAccept() method is typically used:

Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
IPEndPoint iep = new IPEndPoint(IPAddress.Any, 9050);
sock.Bind(iep);
sock.Listen(5);
sock.BeginAccept(new AsyncCallback(CallAccept), sock);
This code snippet creates a Socket object and assigns it to a local IP address and TCP port to listen for incoming connections. The BeginAccpet() method defines the method used as the delegate to be used when a connection attempt is detected on the socket. The last parameter passed to the BeginAccept() method is the original Socket object created.

After the BeginAccept() method is finished, the AsyncCallback method defined will be called when a connection attempt occurs. The AsyncCallback method must include the EndAccept() method to finish the socket accept. Here is the format of the EndAccept() method:

Socket EndAccept(IAsyncResult iar);
The IAsyncResult object parameter passes the IAsyncResult value from the associated BeginAccept() method to the EndAccept() method—this is how the BeginAccept() and EndAccept() pairs are matched.

Similar to the synchronous Accept() method, the EndAccept() method returns a Socket object that is used for the new connection with the client. All further communication with the remote client should be done using this Socket object. A sample section from an EndAccept() AsyncCallback method would look like this:

private static void CallAccept(IAsyncResult iar)
{
Socket server = (Socket)iar.AsyncState;
Socket client = server.EndAccept(iar);
.
.
.
}

The name of the AsyncCallback method must match the name used in the BeginAccept() method parameter. The first step in the method is to retrieve the original server socket. This is done using the AsyncState property of the IAsyncResult class. This property passes the original object placed in the BeginAccept() object parameter. Because it is defined as a generic object, it must be typecast into a Socket object.

After the original Socket object is retrieved, the EndAccept() method can obtain a new Socket object for the client connection. The IAsyncResult object parameter should be the same as that passed to the AsyncCallback method.

The client Socket object, once created, can be used just like any other Socket object, using either synchronous or asynchronous methods to read and write data to the socket.

In the end, the BeginAccept()/EndAccept() asynchronous pair produce the same results as the Accept() synchronous method. You will find that this is true of all the asynchronous Begin() and End() methods. This allows them to be used as direct replacements for the synchronous method calls in network programs that need asynchronous behavior.

The BeginConnect() and EndConnect() Methods
For a client application to connect to a remote server using asynchronous methods, you must use the BeginConnect() method. Its format is as follows:

IAsyncResult BeginConnect(EndPoint ep, AsyncCallback callback, Object state)
The first parameter passed to the BeginConnect() method is the EndPoint value of the remote host to connect to. Like the BeginAccept() method, the BeginConnect() method specifies the AsyncCallback method name of the delegate method to call when the connection is ready for completion. The last parameter is a state object that can be passed to the EndConnect() method to transfer necessary data.

Here is an example of BeginConnect() code:

Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
IPEndPoint iep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9050);
newsock.BeginConnect(iep, new AsyncCallback(Connected), newsock);
This code snippet creates a Socket object newsock and an IPEndPoint object iep for the remote host. The BeginConnect() method references the AsyncCallback method (Connected) and passes the original Socket object newsock to the AsyncCallback method.

When the connection is completed, the AsyncCallback method that was declared is called. The AsyncCallback method uses the EndConnect() method to complete the connection.

The format of the EndConnect() method is as follows:

EndConnect(IAsyncResult iar)

Here again, the IAsyncResult object specified pass the object value from the BeginConnect() method. It will be instantiated with the IAsyncResult object returned by the BeginConnect() method. A sample method to use this would look like the following:

public static void Connected(IAsyncResult iar)
{
Socket sock = (Socket)iar.AsyncState;
try
{
sock.EndConnect(iar);
} catch (SocketException)
{
Console.WriteLine("Unable to connect to host");
}
}
The first statement in the AsyncCallback method retrieves the original socket used for the BeginConnect() method call, using the AsyncState property of the IAsyncResult object passed to the AsyncCallback method.

After the original socket is recreated, the EndConnect() method is called, using the IAsyncResult object to point it back to the original BeginConnect() method. Because it is possible that the remote host will not be available, it is good practice to place the EndConnect() method in a try-catch block. If the EndConnect() method is unsuccessful, it will throw a SocketException error.

Sending and Receiving Data
After a connection is established, you will most likely want to send and receive data with the remote host. Asynchronous methods can also be used to do this.

The BeginSend() and EndSend() Methods
The BeginSend() method sends data to a connected socket. The format of this method is as follows:

IAsyncResult BeginSend(byte[] buffer, int offset, int size,
SocketFlags sockflag, AsyncCallback callback, object state)
As you can see, there are plenty of parameters to use with the BeginSend() method. You may notice that most of them are similar to the synchronous Send() method. Walking through them, the first one is the byte array that contains the data you want sent. The offset parameter points to the location within the buffer parameter from which to start sending data, and the size parameter specifies how many bytes from the buffer parameter to send. Next, the sockflag parameter specifies any special socket flags that you want set for the communication. Finally, the AsyncCallback callback and state objects are specified, defining the method to call when the BeginSend() method succeeds and a state object to send information to the EndSend() method.

A sample BeginSend() method would look like this:

sock.BeginSend(data, 0, data.Length, SocketFlags.None,
new AsyncCallback(SendData), sock);
This example sends the entire data buffer and calls the SendData() method when the socket is ready to send the data. The sock Socket object is passed to the AsynCallback() method.

The EndSend() method completes the sending of the data. The format for this method is as follows, where the IAsyncResult parameter defines an empty object that references the result of the BeginSend() method call:

int EndSend(IAsyncResult iar)
The EndSend() method returns the number of bytes successfully sent from the socket.

Here’s an example of the EndSend() AsyncCallback method:

private static void SendData(IAsyncResult iar)
{
Socket server = (Socket)iar.AsyncState;
int sent = server.EndSend(iar);
}
The original sock socket is re-created using the AsyncState property of the IAsyncResult object passed to the AsyncCallback method. Again, this relates to the state object specified in the BeginSend() method.

The BeginSendTo() and EndSendTo() Methods
The BeginSendTo() method is used with connectionless sockets to start an asynchronous data transmission to a remote host. The format of the BeginSendTo() method is as follows:

IAsyncResult BeginSendTo(byte[] buffer, int offset, int size,
SocketFlags sockflag, EndPoint ep, AsyncCallback callback, object state)
As you can see, for the most part the BeginSendTo() method format is similar to the SendTo() method format, with the asynchronous features of the BeginSend() method added. The BeginSendTo() method allows you to specify the EndPoint object of the remote host to which to send the message.

Sample sBeginSendTo() code would look like this:

IPEndPoint iep = new IPEndPoint(IPAddress.Parse("192.168.1.6"), 9050);
sock.BeginSendTo(data, 0, data.Length, SocketFlags.None, iep,
new AsynCallback(SendDataTo), sock);

Again, the only difference between this call and the BeginSend() call is the IPEndPoint of the remote host added to the parameters.

The EndSendTo() method uses the standard format of End methods:

int EndSendTo(IAsyncResult iar)
As always, the IAsyncResult parameter accepts the IAsyncResult value returned by the BeginSendTo() method. The EndSendTo() method returns the number of bytes sent out from the socket.

The BeginReceive() and EndReceive() Methods
The BeginReceive() method accepts data from a remote host on a socket. The format for this method is as follows:

IAsyncResult BeginReceive(byte[] buffer, int offset, int size,
SocketFlags sockflag, AsyncCallback callback, object state)
The first parameter is a byte array that accepts the incoming data. The offset and size parameters are used to specify where in the buffer to start placing the data, and how large the buffer is. The sockflags parameter sets any needed socket flags for the communication. The callback and state parameters allows you to pass information to the EndReceive() method.

Here’s a sample BeginReceive() method call:

sock.BeginReceive(data, 0, data.Length, SocketFlags.None,
new AsyncCallback(ReceivedData), sock);
The BeginReceive() method passes the original socket to the EndReceive() method so that it can re-create the socket for the AsyncCallback method. The AsyncCallback method used for the EndReceive() method would look like this:

void ReceivedData(IAsyncResult iar)
{
Socket remote = (Socket)iar.AsyncState;
int recv = remote.EndReceive(iar);
string receivedData = Encoding.ASCII.GetString(data, 0, recv);
Console.WriteLine(stringData);
}
You see the same AsyncCallback behavior again: the first statement recreates the original socket from the IAsyncResult object. The second statement uses the socket to finish the socket receive, via the EndReceive() method call. Incoming data is placed in the data buffer specified in the corresponding BeginReceive() method call. To access the data buffer from the AsyncCallback method, you must ensure that it is accessible from both methods (such as using a global variable or data class).

The BeginReceiveFrom() and EndReceiveFrom() Methods
The BeginReceiveFrom() method accepts data from any remote host on a connectionless socket. Here is the format:

IAsyncResult BeginReceiveFrom(byte[] buffer, int offset, int size,
SocketFlags sockflag, ref EndPoint ep, AsyncCallback callback, object state)
Notice that the BeginReceiveFrom() method is similar to the BeginReceive() method, except that it specifies a reference to an EndPoint object. The EndPoint object defines the remote host IP address and port number that sent the data.

Warning Remember that the BeginReceiveFrom() method uses a reference to an EndPoint object, not the object itself. It’s easy to forget that ref keyword and thus have a problem on your hands.


A sample BeginReceiveFrom() method would look like this:

sock.BeginReceive(data, 0, data.Length, SocketFlags.None, ref iep, new AsyncCallback(ReceiveData), sock);
The corresponding EndReceiveFrom() method is placed in the appropriate AsyncCallback method:

void ReceiveData(IasyncResult iar)
{
Socket remote = (Socket)iar.AsyncState;
int recv = remote.EndReceiveFrom(iar);
string stringData = Encoding.ASCII.GetString(data, 0, recv);
Console.WriteLine(stringData);
}
The EndReceiveFrom() method returns the number of bytes read from the socket and places the received data in the data buffer defined in the BeginReceiveFrom() method. Again, if you need to access this data within the AsyncCallback method, you should ensure that the data buffer is accessible from both methods.

RDP Clients

I founded a while ago mRemote which helps me to have only one tool to connect multiple servers without to enter any time the password. Now I found an additional Remote Desktop Manager tool on codeproject - Palantir and I was curious what are the main parts to manage a remote desktop connection.

Therefore I have stripped out the intersting part:


private AxMSTSCLib.AxMsRdpClient4 rdpc = null;

protected override void OnCreateControl()
{
rdpc = new AxMSTSCLib.AxMsRdpClient4();
rdpc.OnDisconnected += new AxMSTSCLib.IMsTscAxEvents_OnDisconnectedEventHandler(rdpc_OnDisconnected);
this.Controls.Add(rdpc);
rdpc.Dock = DockStyle.Fill;
base.OnCreateControl();
}

public void Disconnect()
{
try
{
if (rdpc.Connected == 1)
{
rdpc.Disconnect();
}
}
catch (Exception)
{ }
}

private void SetRdpClientProperties(Machine parMachine)
{
rdpc.Server = parMachine.MachineName;
rdpc.UserName = parMachine.UserName;
rdpc.Domain = parMachine.DomainName;
if (parMachine.Password != "")
{
rdpc.AdvancedSettings5.ClearTextPassword = parMachine.Password;
}
rdpc.AdvancedSettings5.RedirectDrives = parMachine.ShareDiskDrives;
rdpc.AdvancedSettings5.RedirectPrinters = parMachine.SharePrinters;
rdpc.ColorDepth = (int)parMachine.ColorDepth;
rdpc.Dock = DockStyle.Fill;

}

public void Connect(Machine parMachine)
{
SetRdpClientProperties(parMachine);
rdpc.Connect();
}

public void ConnectViaConsole(Machine parMachine)
{
rdpc.AdvancedSettings5.ConnectToServerConsole = true;
SetRdpClientProperties(parMachine);

rdpc.Connect();
}



The AxMSTSCLib.AxMsRdpClient4 and AxInterop.MSTSCLib dll's can be downloaded from codeproject - Palantir directly or from the following location as a zip file:
http://www.ronischuetz.com/download/Interop.MSTSCLib_and_AxInterop.MSTSCLib.zip


Update: additional description how you add the dll's directly: http://www.codeproject.com/KB/cs/RemoteDesktop_CSharpNET.aspx

Friday, April 30, 2010

Whats new in Visual Studio 2010 (VSTS 2010)

Visual Studio 2010 is released and a bunch of new stuff is available. This post is describes certain things i could gather on the web.

From MSDN:

C# 4.0 Language and Compiler

Dynamic Support
Visual C# 2010 provides support for late binding to dynamic types by introducing a new type, dynamic. This addition enables many new scenarios, including simplified access to COM APIs such as the Office Automation APIs, to dynamic APIs such as IronPython libraries, and to the HTML Document Object Model (DOM). For more information, see Using Type dynamic (C# Programming Guide) and dynamic (C# Reference).

Office Programmability
Access to COM interfaces, including the Office Automation APIs, is greatly enhanced by the addition of named and optional arguments, the dynamic type, indexed properties and optional ref modifiers.

For more information, see Named and Optional Arguments (C# Programming Guide), Using Type dynamic (C# Programming Guide), How to: Use Indexed Properties in COM Interop Programming (C# Programming Guide), and How to: Access Office Interop Objects by Using Visual C# 2010 Features (C# Programming Guide).

Type Equivalence Support
You can now deploy an application that has embedded type information instead of type information that is imported from a Primary Interop Assembly (PIA). With embedded type information, your application can use types in a runtime without requiring a reference to the runtime assembly. If various versions of the runtime assembly are published, the application that contains the embedded type information can work with the various versions without having to be recompiled. For more information, see /link (C# Compiler Options). For an example, see Walkthrough: Embedding Types from Managed Assemblies (C# and Visual Basic).

Covariance and Contravariance
Covariance enables you to use a more derived type than that specified by the generic parameter, whereas contravariance enables you to use a less derived type. This allows for implicit conversion of classes that implement variant interfaces and provides more flexibility for matching method signatures with variant delegate types. Variant interfaces and delegates can be created by using the new in and out language keywords. The .NET Framework also introduces variance support for several existing generic interfaces and delegates, including the IEnumerable(Of T) interface and the Func(Of TResult) and Action(Of T) delegates. For more information, see Covariance and Contravariance (C# and Visual Basic).

New Command-Line Options
The /langversion command-line option causes the compiler to accept only syntax that is valid in the specified version of C#.

The /appconfig compiler option enables a C# application to specify the location of an assembly's application configuration file to the compiler.

Visual C# Integrated Development Environment
--------------------------------------------------------------------------------

The following sections describe enhancements to the Visual Studio integrated development environment (IDE).

Call Hierarchy
Call Hierarchy enables you to navigate through your code by displaying the following:


  • All calls to and from a selected method, property, or constructor

  • All implementations of an interface member

  • All overrides of a virtual or abstract member



This enables you to better understand how code flows and to evaluate the effects of changes to code. For more information, see Call Hierarchy.




Navigate To
You can use the Navigate To feature to search for a symbol or file in source code. You can search for keywords that are contained in a symbol by using Camel casing and underscore characters to divide the symbol into keywords.

For more information, see How to: Search for Objects, Definitions, and References (Symbols).

Highlighting References
When you click a symbol in source code, all instances of that symbol are highlighted in the document. To move to the next or previous highlighted symbol, you can use CTRL+SHIFT+DOWN ARROW or CTRL+SHIFT+UP ARROW. For more information, see How to: Use Reference Highlighting.

Generate From Usage
The Generate From Usage feature enables you to use classes and members before you define them. Without leaving your current location in code, you can generate a stub for a class, constructor, method, property, field, or enum that you want to use but have not yet defined. This minimizes interruption to your workflow.

Generate From Usage supports programming styles such as test-first development. For more information, see Generate From Usage and Walkthrough: Test-First Support with the Generate From Usage Feature.

IntelliSense Suggestion Mode
IntelliSense now provides two alternatives for IntelliSense statement completion: completion mode and suggestion mode. Suggestion mode is used when classes and members are used before they are defined. For more information, see List Members.

Live Semantic Errors
The Live Semantic Errors feature has been enhanced in Visual C# 2010. The use of wavy underlines to signal errors and warnings as you type has been extended to include constructs that are outside of method bodies, such as return types, parameter types, and default values in method declarations.

Tuesday, April 20, 2010

The security validation for this page is invalid. Click Back in your Web

While i was developing certain Sharepoint MOSS 2007 maintenance stuff I received the following error:

"The security validation for this page is invalid. Click Back in your Web..."

I developed the code against MOSS API and not on the website and was a kind of irritated about it!

The solution to solve this can be one of the following ways:

Option A)
turn off the security validation over your central administration:
- Central Administration
- Application Management
- Web Application Aettings
- "turn security validation off"

Option B)
You can modify the setting also within you coding:

SPSecurity.RunWithElevatedPrivileges(new SPSecurity.CodeToRunElevated(
delegate()
{
using (SPSite oSite = new SPSite("http://your.website.com/"))
{
using (SPWeb web = oSite.OpenWeb())
{
SPWebApplication webApp = web.Site.WebApplication;
webApp.FormDigestSettings.Enabled = false;
web.AllowUnsafeUpdates = true;


web.AllowUnsafeUpdates = false;
webApp.FormDigestSettings.Enabled = true;
web.close();
}
}
}
)
);

Monday, April 12, 2010

.Net C#: Binary Tree

needed using's are the following onces:

In computer science, a binary tree is a tree data structure in which each node has at most two children. Typically the first node is known as the parent and the child nodes are called left and right. In type theory, a binary tree with nodes of type A is defined inductively as TA = μα. 1 + A × Î± × Î±. Binary trees are commonly used to implement binary search trees and binary heaps.

if you need more information about binary tree please check-out the following link on Wikipedia: http://en.wikipedia.org/wiki/Binary_tree


using System;
using System.Collections.Generic;

    /// <summary>
/// Binary tree
/// </summary>
/// <typeparam name="T">The type held by the nodes</typeparam>
public class BinaryTree<T> : ICollection<T>,IEnumerable<T> where T : IComparable<T>
{
#region Constructor

/// <summary>
/// Constructor
/// </summary>
public BinaryTree()
{
NumberOfNodes = 0;
}

public BinaryTree(TreeNode<T> Root)
{
this.Root = Root;
NumberOfNodes = 0;
}

#endregion

#region Properties
/// <summary>
/// The root value
/// </summary>
public TreeNode<T> Root { get; set; }

/// <summary>
/// The number of nodes in the tree
/// </summary>
protected int NumberOfNodes { get; set; }

/// <summary>
/// Is the tree empty
/// </summary>
public bool IsEmpty { get { return Root == null; } }

/// <summary>
/// Gets the minimum value of the tree
/// </summary>
public T MinValue
{
get
{
if (IsEmpty)
throw new Exception("The tree is empty");
TreeNode<T> TempNode = Root;
while (TempNode.Left != null)
TempNode = TempNode.Left;
return TempNode.Value;
}
}

/// <summary>
/// Gets the maximum value of the tree
/// </summary>
public T MaxValue
{
get
{
if (IsEmpty)
throw new Exception("The tree is empty");
TreeNode<T> TempNode = Root;
while (TempNode.Right != null)
TempNode = TempNode.Right;
return TempNode.Value;
}
}

#endregion

#region IEnumerable<T> Members

public IEnumerator<T> GetEnumerator()
{
foreach (TreeNode<T> TempNode in Traversal(Root))
{
yield return TempNode.Value;
}
}

#endregion

#region IEnumerable Members

System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
foreach (TreeNode<T> TempNode in Traversal(Root))
{
yield return TempNode.Value;
}
}

#endregion

#region ICollection<T> Members

public void Add(T item)
{
if (Root == null)
{
Root = new TreeNode<T>(item);
++NumberOfNodes;
}
else
{
Insert(item);
}
}

public void Clear()
{
Root = null;
}

public bool Contains(T item)
{
if(IsEmpty)
return false;

TreeNode<T> TempNode=Root;
while (TempNode != null)
{
int ComparedValue = TempNode.Value.CompareTo(item);
if (ComparedValue == 0)
return true;
else if (ComparedValue < 0)
TempNode = TempNode.Left;
else
TempNode = TempNode.Right;
}
return false;
}

public void CopyTo(T[] array, int arrayIndex)
{
T[] TempArray = new T[NumberOfNodes];
int Counter = 0;
foreach (T Value in this)
{
TempArray[Counter] = Value;
++Counter;
}
Array.Copy(TempArray, 0, array, arrayIndex, this.NumberOfNodes);
}

public int Count
{
get { return NumberOfNodes; }
}

public bool IsReadOnly
{
get { return false; }
}

public bool Remove(T item)
{
TreeNode<T> Item = Find(item);
if (Item == null)
return false;
List<T> Values = new List<T>();
foreach (TreeNode<T> TempNode in Traversal(Item.Left))
{
Values.Add(TempNode.Value);
}
foreach (TreeNode<T> TempNode in Traversal(Item.Right))
{
Values.Add(TempNode.Value);
}
if (Item.Parent.Left == Item)
{
Item.Parent.Left = null;
}
else
{
Item.Parent.Right = null;
}
Item.Parent = null;
foreach (T Value in Values)
{
this.Add(Value);
}
return true;
}

#endregion

#region Private Functions

/// <summary>
/// Finds a specific object
/// </summary>
/// <param name="item">The item to find</param>
/// <returns>The node if it is found</returns>
protected TreeNode<T> Find(T item)
{
foreach (TreeNode<T> Item in Traversal(Root))
if (Item.Value.Equals(item))
return Item;
return null;
}

/// <summary>
/// Traverses the list
/// </summary>
/// <param name="Node">The node to start the search from</param>
/// <returns>The individual items from the tree</returns>
protected IEnumerable<TreeNode<T>> Traversal(TreeNode<T> Node)
{
if (Node.Left != null)
{
foreach (TreeNode<T> LeftNode in Traversal(Node.Left))
yield return LeftNode;
}
yield return Node;
if (Node.Right != null)
{
foreach (TreeNode<T> RightNode in Traversal(Node.Right))
yield return RightNode;
}
}

/// <summary>
/// Inserts a value
/// </summary>
/// <param name="item">item to insert</param>
protected void Insert(T item)
{
TreeNode<T> TempNode = Root;
bool Found=false;
while (!Found)
{
int ComparedValue = TempNode.Value.CompareTo(item);
if(ComparedValue<0)
{
if(TempNode.Left==null)
{
TempNode.Left=new TreeNode<T>(item,TempNode);
++NumberOfNodes;
return;
}
else
{
TempNode=TempNode.Left;
}
}
else if(ComparedValue>0)
{
if(TempNode.Right==null)
{
TempNode.Right=new TreeNode<T>(item,TempNode);
++NumberOfNodes;
return;
}
else
{
TempNode=TempNode.Right;
}
}
else
{
TempNode=TempNode.Right;
}
}
}

#endregion
}

/// <summary>
/// Node class for the Binary tree
/// </summary>
/// <typeparam name="T">The value type</typeparam>
public class TreeNode<T>
{
#region Constructors

/// <summary>
/// Constructor
/// </summary>
public TreeNode()
{
}

/// <summary>
/// Constructor
/// </summary>
/// <param name="Value">Value of the node</param>
public TreeNode(T Value)
{
this.Value = Value;
}

/// <summary>
/// Constructor
/// </summary>
/// <param name="Value">Value of the node</param>
/// <param name="Parent">Parent node</param>
public TreeNode(T Value, TreeNode<T> Parent)
{
this.Value = Value;
this.Parent = Parent;
}

/// <summary>
/// Constructor
/// </summary>
/// <param name="Value">Value of the node</param>
/// <param name="Parent">Parent node</param>
/// <param name="Left">Left node</param>
/// <param name="Right">Right node</param>
public TreeNode(T Value, TreeNode<T> Parent, TreeNode<T> Left, TreeNode<T> Right)
{
this.Value = Value;
this.Right = Right;
this.Left = Left;
this.Parent = Parent;
}

#endregion

#region Properties

/// <summary>
/// Value of the node
/// </summary>
public T Value { get; set; }

/// <summary>
/// Parent node
/// </summary>
public TreeNode<T> Parent { get; set; }

/// <summary>
/// Left node
/// </summary>
public TreeNode<T> Left { get; set; }

/// <summary>
/// Right node
/// </summary>
public TreeNode<T> Right { get; set; }

/// <summary>
/// Is this the root
/// </summary>
public bool IsRoot { get { return Parent == null; } }

/// <summary>
/// Is this a leaf
/// </summary>
public bool IsLeaf { get { return Left == null && Right == null; } }

internal bool Visited { get; set; }

#endregion

#region Public Overridden Functions

public override string ToString()
{
return Value.ToString();
}

#endregion
}

Shared Cache - .Net Caching made easy

All information about Shared Cache is available here: http://www.sharedcache.com/. Its free and easy to use, we provide all sources at codeplex.

Facebook Badge