Sunday, May 30, 2010

Top Shoots from my tenerife scoba dive week - mai 2010

more pictures can be found on my facebook profile (pic. are public available) .




If you like to dive in tenerife so I can suggest to visit Aqua-Marina. Great stuff available over there and they speak various languages - a multi-culti stuff is around there.






















































Sunday, May 09, 2010

serializing.info

bought a new domain name: serializing.info

under this domain I would like to aggregate various information around serializing. if you have content which you would like to distribute here you're welcome to send me an email.

Finance Terms - always good to know

1. NAV
a. Net Asset Value
b. The value of the mutual –fund calculated daily (sometime more)
c. Total value of fund-dividend \ num of shares issued

2.OCIC
a. Open End Investment Company
b. A type of a mutual fund

3.SEC
a. Securities and Exchange Commission

4.IRA
a. Individual retirement Account
b. Allow to set 2K $ per year in MF without tax

5.ICI
a. Investment Company Institute
b. National association of Investment companies

6. Sector-Funds
a. A type of industry to invest in
b. Technology, biomedical, etc…

7. POP
a. Public Offering Price
b. When selling a MF
c. NAV + sales charge

8. Turnover
a. When a MF invests in securities, it sells and buys
these securities if a capital gain was achieved the
share holders of the MF will be taxed and will also
pay for the buying \ selling fees
b. Tot buy + sell \ 2 * fund total holdings

9. MF – FEES
a. Management fees
actual fees on managing the fund + administration
b. Non management fees
fees for other non managing parties like custodial,
accountant, board of directors, SEC registration
fee etc…
c. 12b-1 + non 12b-1 fees
12b1 – Marketing expenses of the fund according to the SEC rules
non 12b1 – other marketing not under SEC rules
d. Fees by the investor based on arrangements with the investor's broker

10. CDSL
a. Contingent Deferred Sales Load

11. TER
a. funds Total Expense Ratio

Saturday, May 08, 2010

Disk I/O optimization

Disk I/O refers to the number of read and write operations performed by your
application on a physical disk or multiple disks installed in your server. Common
activities that can cause disk I/O-related bottlenecks include long-running file I/O
operations, data encryption and decryption, reading unnecessary data from database
tables, and a shortage of physical memory that leads to excessive paging activity.
Slow hard disks are another factor to consider.

To resolve disk-related bottlenecks:
- Start by removing any redundant disk I/O operations in your application.
- Identify whether your system has a shortage of physical memory, and,
if so, add more memory to avoid excessive paging.
- Identify whether you need to separate your data onto multiple disks.
- Consider upgrading to faster disks if you still have disk I/O
bottlenecks after doing all of above.

Configuration Overview
Microsoft Windows retrieves programs and data from disk. The disk
subsystem can be the most important aspect of I/O performance, but
problems can be masked by other factors, such as lack of memory.
Performance console disk counters are available within both the
LogicalDisk or PhysicalDisk objects.

Metrics
PhysicalDisk
- Avg. Disk Queue Length
- Avg. Disk Read Queue Length
- Avg. Disk Write Queue Length
- Avg. Disk sec/Read
- Avg. Disk sec/Transfer
- Disk Writes/sec


Tuning Options
If you determine that disk I/O is a bottleneck, you have a number of options:
- Defragment your disks. Use the Disk Defragmenter system tool.
- Use Diskpar.exe on Windows 2000 to reduce performance loss due to misaligned
disk tracks and sectors. You can use get the Diskpar.exe from the Windows 2000
Resource Kit.
- Use stripe sets to process I/O requests concurrently over multiple disks. The
type you use depends on your data-integrity requirements. If your applications
are read-intensive and require fault tolerance, consider a RAID 5 volume. Use
mirrored volumes for fault tolerance and good I/O performance overall. If you do
not require fault tolerance, implement stripe sets for fast reading and writing and
improved storage capacity. When stripe sets are used, disk utilization per disk
should fall due to distribution of work across the volumes, and overall throughput
should increase.
- If you find that there is no increased throughput when scaling to additional disks
in a stripe set, your system might be experiencing a bottleneck due to contention
between disks for the disk adapter. You might need to add an adapter to better
distribute the load.
- Place multiple drives on separate I/O buses, particularly if a disk has an
I/O-intensive workload.
- Distribute workload among multiple drives. Windows Clustering and
Distributed File System provide solutions for load balancing on different drives.
- Limit your use of file compression or encryption. File compression and
encryption are I/O-intensive operations. You should only use them where
absolutely necessary.
- Disable creation of short names. If you are not supporting MS-DOS for Windows
3.x clients, disable short names to improve performance. To disable short names,
change the default value of the \NtfsDisable8dot3NameCreation registry entry
(in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Filesystem) to 1.
- Disable last access update. By default, NTFS updates the date and time stamp
of the last access on directories whenever it traverses the directory. For a large
NTFS volume, this update process can slow performance. To disable automatic
updating, create a new REG_DWORD registry entry named
NtfsDisableLastAccessUpdate in HKEY_LOCAL_MACHINE\SYSTEM\CurrentContolSet\Control\Filesystem and set its value to 1.
Reserve appropriate space for the master file table. Add the
NtfsMftZoneReservation entry to the registry as a REG_DWORD in
HKEY_LOCAL_MACHINE \SYSTEM \CurrentControlSet\Control \FileSystem.
When you add this entry to the registry, the system reserves space on the volume
for the master file table. Reserving space in this manner allows the master file
table to grow optimally. If your NTFS volumes generally contain relatively few
files that are large, set the value of this registry entry to 1 (the default).
- Typically you can use a value of 2 or 3 for moderate numbers of files, and use a value of 4 (the maximum) if your volumes tend to contain a relatively large number of files. However, make sure to test any settings greater than 2, because these greater values cause the system to reserve a much larger portion of the disk for the master file table.
- Use the most efficient disk systems available, including controller, I/O, cabling,
and disk. Use intelligent drivers that support interrupt moderation or interrupt
avoidance to alleviate the interrupt activity for the processor due to disk I/O.
- Check whether you are using the appropriate RAID configuration. Use RAID 10
(striping and mirroring) for best performance and fault tolerance. The tradeoff is
that using RAID 10 is expensive. Avoid using RAID 5 (parity) when you have
extensive write operations.
- Consider using database partitions. If you have a database bottleneck, consider
using database partitions and mapping disks to specific tables and transaction
logs. The primary purpose of partitions is to overcome disk bottlenecks for large
tables. If you have a table with large number of rows and you determine that it is
the source of a bottleneck, consider using partitions. For SQL Server, you can use
file groups to improve I/O performance. You can associate tables with file groups,
and then associate the file groups with a specific hard disk.
- Consider splitting files across hard disks. If you are dealing with extensive
file-related operations, consider splitting the files across a number of hard disks
to spread the I/O load across multiple disks.

Memory

Memory consists of physical and virtual memory. You need to consider how much memory is allocated to your application. When you evaluate memory-related bottlenecks, consider unnecessary allocations, inefficient clean up, and inappropriate caching and state management mechanisms. To resolve memory-related bottlenecks, optimize your code to eliminate these issues and then tune the amount of memory allocated to your application. If you determine during tuning that memory contention and excessive paging are occurring, you may need to add more physical memory to the server.

Low memory leads to increased paging where pages of your application’s virtual
address space are written to and from disk. If paging becomes excessive, page
thrashing occurs and intensive disk I/O decreases overall system performance.

Configuration Overview
Memory tuning consists of the following:
- Determine whether your application has a memory bottleneck. If
it has, then add more memory.
- Tune the amount of memory allocated if you can control the
allocation. For example, you can tune this for ASP.NET and
SQL Server.
- Tune the page file size.

Metrics
The performance counters help you identify memory bottlenecks. You should log these counter values to log files over a 24 hour period before you form any conclusions.

Memory
- Available MBytes
- Page Reads/sec
- Pages/sec
- Cache Bytes
- Cache Faults/sec
Server
- Pool Nonpaged Failures
- Pool Nonpaged Peak
Cache
- MDL Read Hits %

Bottlenecks
A low value of Available MBytes indicates that your system is low on physical
memory, caused either by system memory limitations or an application that is not
releasing memory. Monitor each process object’s working set counter. If Available
MBytes remains high even when the process is not active, it might indicate that the
object is not releasing memory. Use the CLR Profiler tool at this point to identify the source of any memory allocation problems. For more information, see “How To: Use
CLR Profiler” in the “How To” section of this guide.

A high value of Pages/sec indicates that your application does not have sufficient
memory. The average of Pages Input/sec divided by average of Page Reads/sec gives
the number of pages per disk read. This value should not generally exceed five pages
per second. A value greater than five pages per second indicates that the system is
spending too much time paging and requires more memory (assuming that the
application has been optimized).

Tuning Options
If you determine that your application has memory issues, your options include
adding more memory, stopping services that you do not require, and removing
unnecessary protocols and drivers. Tuning considerations include:
- Deciding when to add memory
- Page file optimization

Deciding When to Add Memory
To determine the impact of excessive paging on disk activity, multiply the values of
the Physical Disk\ Avg. Disk sec/Transfer and Memory\ Pages/sec counters. If the
product of these counters exceeds 0.1, paging is taking more than 10 percent of disk
access time. If this occurs over a long period, you probably need more memory. After
upgrading your system’s memory, measure and monitor again.

To save memory:
- Turn off services you do not use. Stopping services
that you do not use regularly saves memory and improves
system performance.
- Remove unnecessary protocols and drivers. Even idle
protocols use space in the paged and nonpaged memory
pools. Drivers also consume memory, so you should remove
unnecessary ones.

Page File Optimization
You should optimize the page file to improve the virtual memory performance of
your server. The combination of physical memory and the page file is called the
virtual memory of the system. When the system does not have enough physical
memory to execute a process, it uses the page file on disk as an extended memory
source. This approach slows performance.

To ensure an optimized page file:
- Increase the page file size on the system to 1.5 times
the size of physical memory available, but only to
a maximum of 4,095 MB. The page file needs to be at least
the size of the physical memory to allow the memory to be
written to the page file in the event of a system crash.
- Make sure that the page file is not fragmented on a given partition.
- Separate the data files and the page file to different
disks only if the disk is a bottleneck because of a lot
of I/O operation. These files should preferably be on the
same physical drive and the same logical partition. This
keeps the data files and the page file physically close to
each other and avoids the time spent seeking between two
different logical drives.

To configure the page file size
1. Open Control Panel.
2. Double-click the System icon.
3. Select the Advanced tab.
4. Click Performance Options.
5. Click Change. The Virtual Memory dialog box appears
6. Enter new values for Initial size and Maximum size. Click Set, and then click OK.

regions

#region Variable
#endregion

#region Properties
#endregion

#region Methods

#region Constructor
#endregion

#region Public Methods
#endregion

#region Private or Protected Methods
#endregion
#endregion

Windows 7: Indexing network share locations

I tried to index a network share from my filer but it doesn't appear in my search selections. After few researches I figured out there are 2 options:

Option 1:
a) right click on the share
b) select the choice: "Always Available offline"

Option 2:
a) Create a folder on your hard drive for shares.
-> i.e. c:\myshares
b) Create another folder in the above share:
-> c:\myshares\music
c) Link the Library to this folder.
d) Delete the folder.
e) Use the mklink in an elevated command prompt to make a symbolic link.
Name the link the same as the folder you created above.
i.e - mklink /d c:\myshares\music \\myshares\music
f) Done. Now you have non-indexed UNC path as a library.

enjoy

Thursday, May 06, 2010

Manage Custom Actions on Sharepoint

Today I searched over an hour until I found the following 3 Links regarding custom actions on Sharepoint.



You find there an example for any custom action possibility which GroupId and Location you have to set for a CustomAction.

Thanks to them!

Tuesday, May 04, 2010

zip, zipper and 7zip log files

For various windows servers I had to decrease the amount of log files on the server itself. Therefore I decided the go with the following strategy:


  • leave 3 days of log files as-is on the server

  • files which are older then 3 day's need to be zipped and I keep a copy on the server

  • files which are older then 60 day's can be deleted because they have already copied onto an additional storage (but this copy is a different szenario and I explain about it in a different blog post)
I accomplished this task with the following components:

  1. 7-zip
  2. forfiles.exe (you can download a rar file from my shared cache website)
  3. Windows Task Scheduler
  4. one bat file

The following 3 lines you multiply as much as needed for each WsSVC[n] folder and save it into a *.bat file.

@echo START - %TIME%
forfiles -p "E:\LogFiles\W3SVC1" -s -m *.log -d -3 -c "Cmd /C 7z a @FILE.zip @FILE"
forfiles -p "E:\LogFiles\W3SVC1" -s -m *.log -d -3 -c "cmd /c del @file"
forfiles -p "E:\LogFiles\W3SVC1" -s -m *.zip -d -60 -c "cmd /c del @file"
@echo DONE - %TIME%
I had to compress 24 folder with log files

All files together had a size 684 MB - well quite a lot for log files but they get very fast very big therefore I really suggest to implement this approach.

For my scripting convenience I've added the installation paths into environment path variable:

  1. Open System properties
  2. Click on Environment Variables
  3. Search for PATH and then click edit
  4. Add both full paths to 7zip and forfiles.exe



Now open your Task Scheduler and create a new Task:







Once you done with the configuration you should make a test run with your task.




The result is that I could save 636 MB on my hard disc on the live server. This space can be used for many other things



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());
}
}
}

HTTP/1.1 Method Definitions

The set of common methods for HTTP/1.1 is defined below. Although this set can be expanded, additional methods cannot be assumed to share the same semantics for separately extended clients and servers.

The Host request-header field (section 14.23) MUST accompany all HTTP/1.1 requests.

Safe and Idempotent Methods
Safe Methods
Implementors should be aware that the software represents the user in their interactions over the Internet, and should be careful to allow the user to be aware of any actions they might take which may have an unexpected significance to themselves or others.

In particular, the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered "safe". This allows user agents to represent other methods, such as POST, PUT and DELETE, in a special way, so that the user is made aware of the fact that a possibly unsafe action is being requested.

Naturally, it is not possible to ensure that the server does not generate side-effects as a result of performing a GET request; in fact, some dynamic resources consider that a feature. The important distinction here is that the user did not request the side-effects, so therefore cannot be held accountable for them.

Idempotent Methods
Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request. The methods GET, HEAD, PUT and DELETE share this property. Also, the methods OPTIONS and TRACE SHOULD NOT have side effects, and so are inherently idempotent.

However, it is possible that a sequence of several requests is non- idempotent, even if all of the methods executed in that sequence are idempotent. (A sequence is idempotent if a single execution of the entire sequence always yields a result that is not changed by a reexecution of all, or part, of that sequence.) For example, a sequence is non-idempotent if its result depends on a value that is later modified in the same sequence.

A sequence that never has side effects is idempotent, by definition (provided that no concurrent operations are being executed on the same set of resources).

OPTIONS
The OPTIONS method represents a request for information about the communication options available on the request/response chain identified by the Request-URI. This method allows the client to determine the options and/or requirements associated with a resource, or the capabilities of a server, without implying a resource action or initiating a resource retrieval.

Responses to this method are not cacheable.

If the OPTIONS request includes an entity-body (as indicated by the presence of Content-Length or Transfer-Encoding), then the media type MUST be indicated by a Content-Type field. Although this specification does not define any use for such a body, future extensions to HTTP might use the OPTIONS body to make more detailed queries on the server. A server that does not support such an extension MAY discard the request body.

If the Request-URI is an asterisk ("*"), the OPTIONS request is intended to apply to the server in general rather than to a specific resource. Since a server's communication options typically depend on the resource, the "*" request is only useful as a "ping" or "no-op" type of method; it does nothing beyond allowing the client to test the capabilities of the server. For example, this can be used to test a proxy for HTTP/1.1 compliance (or lack thereof).

If the Request-URI is not an asterisk, the OPTIONS request applies only to the options that are available when communicating with that resource.

A 200 response SHOULD include any header fields that indicate optional features implemented by the server and applicable to that resource (e.g., Allow), possibly including extensions not defined by this specification. The response body, if any, SHOULD also include information about the communication options. The format for such a

body is not defined by this specification, but might be defined by future extensions to HTTP. Content negotiation MAY be used to select the appropriate response format. If no response body is included, the response MUST include a Content-Length field with a field-value of "0".

The Max-Forwards request-header field MAY be used to target a specific proxy in the request chain. When a proxy receives an OPTIONS request on an absoluteURI for which request forwarding is permitted, the proxy MUST check for a Max-Forwards field. If the Max-Forwards field-value is zero ("0"), the proxy MUST NOT forward the message; instead, the proxy SHOULD respond with its own communication options. If the Max-Forwards field-value is an integer greater than zero, the proxy MUST decrement the field-value when it forwards the request. If no Max-Forwards field is present in the request, then the forwarded request MUST NOT include a Max-Forwards field.

GET
The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI. If the Request-URI refers to a data-producing process, it is the produced data which shall be returned as the entity in the response and not the source text of the process, unless that text happens to be the output of the process.

The semantics of the GET method change to a "conditional GET" if the request message includes an If-Modified-Since, If-Unmodified-Since, If-Match, If-None-Match, or If-Range header field. A conditional GET method requests that the entity be transferred only under the circumstances described by the conditional header field(s). The conditional GET method is intended to reduce unnecessary network usage by allowing cached entities to be refreshed without requiring multiple requests or transferring data already held by the client.

The semantics of the GET method change to a "partial GET" if the request message includes a Range header field. A partial GET requests that only part of the entity be transferred, as described in section 14.35. The partial GET method is intended to reduce unnecessary network usage by allowing partially-retrieved entities to be completed without transferring data already held by the client.

The response to a GET request is cacheable if and only if it meets the requirements for HTTP caching described in section 13.

See section 15.1.3 for security considerations when used for forms.

HEAD
The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response. The metainformation contained in the HTTP headers in response to a HEAD request SHOULD be identical to the information sent in response to a GET request. This method can be used for obtaining metainformation about the entity implied by the request without transferring the entity-body itself. This method is often used for testing hypertext links for validity, accessibility, and recent modification.

The response to a HEAD request MAY be cacheable in the sense that the information contained in the response MAY be used to update a previously cached entity from that resource. If the new field values indicate that the cached entity differs from the current entity (as would be indicated by a change in Content-Length, Content-MD5, ETag or Last-Modified), then the cache MUST treat the cache entry as stale.

POST
The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line. POST is designed to allow a uniform method to cover the following functions:

- Annotation of existing resources;
- Posting a message to a bulletin board, newsgroup, mailing list,
or similar group of articles;
- Providing a block of data, such as the result of submitting a
form, to a data-handling process;
- Extending a database through an append operation.
The actual function performed by the POST method is determined by the server and is usually dependent on the Request-URI. The posted entity is subordinate to that URI in the same way that a file is subordinate to a directory containing it, a news article is subordinate to a newsgroup to which it is posted, or a record is subordinate to a database.

The action performed by the POST method might not result in a resource that can be identified by a URI. In this case, either 200 (OK) or 204 (No Content) is the appropriate response status, depending on whether or not the response includes an entity that describes the result.

If a resource has been created on the origin server, the response SHOULD be 201 (Created) and contain an entity which describes the status of the request and refers to the new resource, and a Location header (see section 14.30).

Responses to this method are not cacheable, unless the response includes appropriate Cache-Control or Expires header fields. However, the 303 (See Other) response can be used to direct the user agent to retrieve a cacheable resource.

POST requests MUST obey the message transmission requirements set out in section 8.2.

See section 15.1.3 for security considerations.

PUT
The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI. If a new resource is created, the origin server MUST inform the user agent via the 201 (Created) response. If an existing resource is modified, either the 200 (OK) or 204 (No Content) response codes SHOULD be sent to indicate successful completion of the request. If the resource could not be created or modified with the Request-URI, an appropriate error response SHOULD be given that reflects the nature of the problem. The recipient of the entity MUST NOT ignore any Content-* (e.g. Content-Range) headers that it does not understand or implement and MUST return a 501 (Not Implemented) response in such cases.

If the request passes through a cache and the Request-URI identifies one or more currently cached entities, those entries SHOULD be treated as stale. Responses to this method are not cacheable.

The fundamental difference between the POST and PUT requests is reflected in the different meaning of the Request-URI. The URI in a POST request identifies the resource that will handle the enclosed entity. That resource might be a data-accepting process, a gateway to some other protocol, or a separate entity that accepts annotations. In contrast, the URI in a PUT request identifies the entity enclosed with the request -- the user agent knows what URI is intended and the server MUST NOT attempt to apply the request to some other resource. If the server desires that the request be applied to a different URI,

it MUST send a 301 (Moved Permanently) response; the user agent MAY then make its own decision regarding whether or not to redirect the request.

A single resource MAY be identified by many different URIs. For example, an article might have a URI for identifying "the current version" which is separate from the URI identifying each particular version. In this case, a PUT request on a general URI might result in several other URIs being defined by the origin server.

HTTP/1.1 does not define how a PUT method affects the state of an origin server.

PUT requests MUST obey the message transmission requirements set out in section 8.2.

Unless otherwise specified for a particular entity-header, the entity-headers in the PUT request SHOULD be applied to the resource created or modified by the PUT.

DELETE
The DELETE method requests that the origin server delete the resource identified by the Request-URI. This method MAY be overridden by human intervention (or other means) on the origin server. The client cannot be guaranteed that the operation has been carried out, even if the status code returned from the origin server indicates that the action has been completed successfully. However, the server SHOULD NOT indicate success unless, at the time the response is given, it intends to delete the resource or move it to an inaccessible location.

A successful response SHOULD be 200 (OK) if the response includes an entity describing the status, 202 (Accepted) if the action has not yet been enacted, or 204 (No Content) if the action has been enacted but the response does not include an entity.

If the request passes through a cache and the Request-URI identifies one or more currently cached entities, those entries SHOULD be treated as stale. Responses to this method are not cacheable.

TRACE
The TRACE method is used to invoke a remote, application-layer loop- back of the request message. The final recipient of the request SHOULD reflect the message received back to the client as the entity-body of a 200 (OK) response. The final recipient is either the

origin server or the first proxy or gateway to receive a Max-Forwards value of zero (0) in the request (see section 14.31). A TRACE request MUST NOT include an entity.

TRACE allows the client to see what is being received at the other end of the request chain and use that data for testing or diagnostic information. The value of the Via header field (section 14.45) is of particular interest, since it acts as a trace of the request chain. Use of the Max-Forwards header field allows the client to limit the length of the request chain, which is useful for testing a chain of proxies forwarding messages in an infinite loop.

If the request is valid, the response SHOULD contain the entire request message in the entity-body, with a Content-Type of "message/http". Responses to this method MUST NOT be cached.

CONNECT
This specification reserves the method name CONNECT for use with a proxy that can dynamically switch to being a tunnel (e.g. SSL tunneling).

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();
}
}
}

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