Click here to Skip to main content
15,886,873 members
Articles / Programming Languages / C#

Internet Magic (Proxy Server) Windows Application

Rate me:
Please Sign up or sign in to vote.
3.00/5 (8 votes)
10 Apr 2010CPOL3 min read 68.5K   8.8K   38  
Windows application which creates a proxy server to share Internet over any TCP/IP network
using System;
using System.Net;
using System.Net.Sockets;
using System.Collections;
using IPNumbers;
using System.Windows.Forms;

namespace internet_magic {

///<summary>Specifies the basic methods and properties of a <c>Listener</c> object. This is an abstract class and must be inherited.</summary>
///<remarks>The Listener class provides an abstract base class that represents a listening socket of the proxy server. Descendant classes further specify the protocol that is used between those two connections.</remarks>
public abstract class Listener : IDisposable{
	///<summary>Initializes a new instance of the Listener class.</summary>
	///<param name="Port">The port to listen on.</param>
	///<param name="Address">The address to listen on. You can specify IPAddress.Any to listen on all installed network cards.</param>
	///<remarks>For the security of your server, try to avoid to listen on every network card (IPAddress.Any). Listening on a local IP address is usually sufficient and much more secure.</remarks>
    public Listener (int Port, IPAddress Address){
		this.Port = Port;
		this.Address = Address;
	}
    
	///<summary>Gets or sets the port number on which to listen on.</summary>
	///<value>An integer defining the port number to listen on.</value>
	///<seealso cref ="Address"/>
	///<exception cref="ArgumentException">The specified value is less than or equal to zero.</exception>
	protected int Port {
		get {
			return m_Port;
		}
		set {
			if (value <= 0) 
				throw new ArgumentException();
			m_Port = value;
			Restart();
		}
	}
	///<summary>Gets or sets the address on which to listen on.</summary>
	///<value>An IPAddress instance defining the IP address to listen on.</value>
	///<seealso cref ="Port"/>
	///<exception cref="ArgumentNullException">The specified value is null.</exception>
	protected IPAddress Address {
		get {
			return m_Address;
		}
		set {
			if (value == null)
				throw new ArgumentNullException();
			m_Address = value;
			Restart();
		}
	}
	///<summary>Gets or sets the listening Socket.</summary>
	///<value>An instance of the Socket class that's used to listen for incoming connections.</value>
	///<exception cref="ArgumentNullException">The specified value is null.</exception>
	protected Socket ListenSocket {
		get {
			return m_ListenSocket;
		}
		set {
			if (value == null)
				throw new ArgumentNullException();
			m_ListenSocket = value;
		}
	}
	///<summary>Gets the list of connected clients.</summary>
	///<value>An instance of the ArrayList class that's used to store all the connections.</value>
	protected ArrayList Clients {
		get {
			return m_Clients;
		}
	}
	///<summary>Gets a value indicating whether the Listener has been disposed or not.</summary>
	///<value>An boolean that specifies whether the object has been disposed or not.</value>
	public bool IsDisposed {
		get {
			return m_IsDisposed;
		}
	}
	///<summary>Starts listening on the selected IP address and port.</summary>
	///<exception cref="SocketException">There was an error while creating the listening socket.</exception>
	public void Start() {
		try {
            ListenSocket = new Socket(Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            ListenSocket.Bind(new IPEndPoint(Address, Port));
			ListenSocket.Listen(50);
            ListenSocket.BeginAccept(new AsyncCallback(this.OnAccept), ListenSocket);
            //ListenSocket.Close();
		} catch {
			ListenSocket = null;
			throw new SocketException();
		}
	}
	///<summary>Restarts listening on the selected IP address and port.</summary>
	///<remarks>This method is automatically called when the listening port or the listening IP address are changed.</remarks>
	///<exception cref="SocketException">There was an error while creating the listening socket.</exception>
	protected void Restart() {
		//If we weren't listening, do nothing
		if (ListenSocket == null)
			return;
        
		ListenSocket.Close();
        
		Start();
	}
    
   
	///<summary>Adds the specified Client to the client list.</summary>
	///<remarks>A client will never be added twice to the list.</remarks>
	///<param name="client">The client to add to the client list.</param>
	protected void AddClient(Client client) {
		if (Clients.IndexOf(client) == -1)
			Clients.Add(client);
	}
	///<summary>Removes the specified Client from the client list.</summary>
	///<param name="client">The client to remove from the client list.</param>
	protected void RemoveClient(Client client) {
		Clients.Remove(client);
	}
	///<summary>Returns the number of clients in the client list.</summary>
	///<returns>The number of connected clients.</returns>
	public int GetClientCount() {
		return Clients.Count;
	}
	///<summary>Returns the requested client from the client list.</summary>
	///<param name="Index">The index of the requested client.</param>
	///<returns>The requested client.</returns>
	///<remarks>If the specified index is invalid, the GetClientAt method returns null.</remarks>
	public Client GetClientAt(int Index) {
		if (Index < 0 || Index >= GetClientCount())
			return null;
		return (Client)Clients[Index];
	}
	///<summary>Gets a value indicating whether the Listener is currently listening or not.</summary>
	///<value>A boolean that indicates whether the Listener is currently listening or not.</value>
	public bool Listening {
		get {
			return ListenSocket != null;
		}
	}
	///<summary>Disposes of the resources (other than memory) used by the Listener.</summary>
	///<remarks>Stops listening and disposes <em>all</em> the client objects. Once disposed, this object should not be used anymore.</remarks>
	///<seealso cref ="System.IDisposable"/>
	public void Dispose() {
		if (IsDisposed)
			return;
		while (Clients.Count > 0) {
			((Client)Clients[0]).Dispose();
		}
		try {
			ListenSocket.Shutdown(SocketShutdown.Both);
            ListenSocket.Close();
		} catch {}
		if (ListenSocket != null)
			ListenSocket.Close();
		m_IsDisposed = true;
	}
	///<summary>Finalizes the Listener.</summary>
	///<remarks>The destructor calls the Dispose method.</remarks>
	~Listener() {
		Dispose();
	}
	///<summary>Returns an external IP address of this computer, if present.</summary>
	///<returns>Returns an external IP address of this computer; if this computer does not have an external IP address, it returns the first local IP address it can find.</returns>
	///<remarks>If this computer does not have any configured IP address, this method returns the IP address 0.0.0.0.</remarks>
	public static IPAddress GetLocalExternalIP() {
		try {
            IPHostEntry he = Dns.Resolve(Dns.GetHostName());
			for (int Cnt = 0; Cnt < he.AddressList.Length; Cnt++) {
				if (IsRemoteIP(he.AddressList[Cnt]))
					return he.AddressList[Cnt];
			}
			return he.AddressList[0];
		} catch {
			return IPAddress.Any;
		}
	}
	///<summary>Checks whether the specified IP address is a remote IP address or not.</summary>
	///<param name="IP">The IP address to check.</param>
	///<returns>True if the specified IP address is a remote address, false otherwise.</returns>
	protected static bool IsRemoteIP(IPAddress IP) {
        IPList iplist = new IPList(); 
        iplist.AddRange("10.0.0.0", "10.0.255.255");
               
        iplist.AddRange("172.16.0.0", "172.31.255.255");
        
        iplist.AddRange("192.168.0.0", "192.168.255.255");

        return (iplist.CheckNumber(IP.ToString()) && (!IP.Equals(IPAddress.Any)) &&
                (!IP.Equals(IPAddress.Loopback)) && (!IP.Equals(IPAddress.Broadcast)));

		
		//Not 10.x.x.x And Not 172.16.x.x <-> 172.31.x.x And Not 192.168.x.x
		//And Not Any And Not Loopback And Not Broadcast
		
	}
	///<summary>Checks whether the specified IP address is a local IP address or not.</summary>
	///<param name="IP">The IP address to check.</param>
	///<returns>True if the specified IP address is a local address, false otherwise.</returns>
	protected static bool IsLocalIP(IPAddress IP) {
        IPList iplist = new IPList();
        iplist.AddRange("10.0.0.0", "10.0.255.255");

        iplist.AddRange("172.16.0.0", "172.31.255.255");

        iplist.AddRange("192.168.0.0", "192.168.255.255");

        return (iplist.CheckNumber(IP.ToString()) && (!IP.Equals(IPAddress.Any)) &&
                (!IP.Equals(IPAddress.Loopback)) && (!IP.Equals(IPAddress.Broadcast)));

		//10.x.x.x Or 172.16.x.x <-> 172.31.x.x Or 192.168.x.x
		
	}
	///<summary>Returns an internal IP address of this computer, if present.</summary>
	///<returns>Returns an internal IP address of this computer; if this computer does not have an internal IP address, it returns the first local IP address it can find.</returns>
	///<remarks>If this computer does not have any configured IP address, this method returns the IP address 0.0.0.0.</remarks>
	public static IPAddress GetLocalInternalIP() {
		try {
            IPHostEntry he = Dns.Resolve(Dns.GetHostName());
			for (int Cnt = 0; Cnt < he.AddressList.Length; Cnt++) {
				if (IsLocalIP(he.AddressList[Cnt]))
					return he.AddressList[Cnt];
			}
			return he.AddressList[0];
		} catch {
			return IPAddress.Any;
		}
	}
	///<summary>Called when there's an incoming client connection waiting to be accepted.</summary>
	///<param name="ar">The result of the asynchronous operation.</param>
	public abstract void OnAccept(IAsyncResult ar);
    ///<summary>Returns a string representation of this object.</summary>
	///<returns>A string with information about this object.</returns>
	public override abstract string ToString();
	///<summary>Returns a string that holds all the construction information for this object.</summary>
	///<value>A string that holds all the construction information for this object.</value>
	public abstract string ConstructString {get;}

   
	// private variables
	/// <summary>Holds the value of the Port property.</summary>
	private int m_Port;
	/// <summary>Holds the value of the Address property.</summary>
	private IPAddress m_Address;
	/// <summary>Holds the value of the ListenSocket property.</summary>
	private Socket m_ListenSocket;
	/// <summary>Holds the value of the Clients property.</summary>
	private ArrayList m_Clients = new ArrayList();
	/// <summary>Holds the value of the IsDisposed property.</summary>
	private bool m_IsDisposed = false;
    
}

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions