Monday, July 26, 2010

C# work with local IP address

/// 
/// Ref: How To Get IP Address Of A Machine
/// Ref: WMI or How to change my IP address
/// using System.Management;
///

public string getLocalIP()
{
string localIP = "";
string strHostName = Dns.GetHostName();

IPHostEntry ipEntry = Dns.GetHostByName (strHostName);
IPAddress [] addr = ipEntry.AddressList;

/* what if more than one instance exists? */
for (int i = 0; i < addr.Length; i++)
{
localIP = addr[i].ToString();
}

return localIP;
}


public bool setLocalIP(string newIP) {
try
{
ManagementBaseObject inPar = null;
ManagementBaseObject outPar = null;
ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject mo in moc)
{
if (!(bool) mo["IPEnabled"]) continue;
inPar = mo.GetMethodParameters("EnableStatic");
inPar["IPAddress"] = new string[] {newIP};
inPar["SubnetMask"] = new string[] {subnetMask};
outPar = mo.InvokeMethod("EnableStatic", inPar, null);
break;
}

this.currentIP = newIP;
return true;
}
catch (Exception e)
{
this.setErrMsg(e.Message + "\nsource: " + e.Source);
return false;
}
}


static void SwitchToDHCP()
{
ManagementBaseObject inPar = null;
ManagementBaseObject outPar = null;
ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
foreach( ManagementObject mo in moc )
{
if( ! (bool) mo["IPEnabled"] )
continue;

inPar = mo.GetMethodParameters("EnableDHCP");
outPar = mo.InvokeMethod( "EnableDHCP", inPar, null );
break;
}
}


static void SwitchToStatic()
{
string newIP;
string subnetMask = "255.255.255.0";
newIP = (curIP.Equals("192.168.168.209"))?"192.168.168.204":"192.168.168.209";

ManagementBaseObject inPar = null;
ManagementBaseObject outPar = null;
ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
foreach( ManagementObject mo in moc )
{
if( ! (bool) mo[ "IPEnabled" ] )
continue;

inPar = mo.GetMethodParameters( "EnableStatic" );
inPar["IPAddress"] = new string[] { newIP };
inPar["SubnetMask"] = new string[] { subnetMask };
outPar = mo.InvokeMethod( "EnableStatic", inPar, null );
break;
}
}


static void ReportIP()
{
Console.WriteLine( "****** Current IP addresses:" );
ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
foreach( ManagementObject mo in moc )
{
if( ! (bool) mo[ "IPEnabled" ] )
continue;

Console.WriteLine( "{0}\n SVC: '{1}' MAC: [{2}]", (string) mo["Caption"],
(string) mo["ServiceName"], (string) mo["MACAddress"] );

string[] addresses = (string[]) mo[ "IPAddress" ];
string[] subnets = (string[]) mo[ "IPSubnet" ];

Console.WriteLine( " Addresses :" );
foreach(string sad in addresses)
Console.WriteLine( "\t'{0}'", sad );

Console.WriteLine( " Subnets :" );
foreach(string sub in subnets )
Console.WriteLine( "\t'{0}'", sub );

curIP = addresses[0];
}
}

C# GET/POST request, login, download, axWebBrowser

///
/// Example of HTTP Get request.
///
private string requestURL(string url, int timeout)
{
HttpWebRequest wr;
HttpWebResponse resp = null;
Stream stream;
StreamReader reader;
string strResponse = "";

try {
wr = (HttpWebRequest) WebRequest.Create(url);
wr.Timeout = timeout; // in milliseconds.
resp = (HttpWebResponse) wr.GetResponse();
stream = resp.GetResponseStream();
reader = new StreamReader(stream);
try { strResponse = reader.ReadToEnd(); }
finally { reader.Close(); }
resp = null;
}
catch (Exception ex) {
this.output_response("::" + ex.Message);
}
finally {
if (resp != null) resp.Close();
}
return strResponse;
}


///
/// Example of HTTP Post request.
/// Call the following function: e.g.
/// string html = HttpPost("http://abcde.com", "a=1&b=2");
///
private string HttpPost(string URI, string Parameters)
{
WebRequest req = WebRequest.Create(URI);
//req.Proxy = new System.Net.WebProxy(ProxyString, true);

req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";

byte [] bytes = System.Text.Encoding.ASCII.GetBytes(Parameters);
req.ContentLength = bytes.Length;

Stream os = req.GetRequestStream ();
os.Write (bytes, 0, bytes.Length);
os.Close ();

WebResponse resp = req.GetResponse();
if (resp== null) return null;

StreamReader sr = new StreamReader(resp.GetResponseStream());
return sr.ReadToEnd().Trim();
}


///
/// Example of using HTTP Post to log into a site.
///
private void login() {
HTMLDocument myDoc = new HTMLDocumentClass();
myDoc = (HTMLDocument) axWebBrowser1.Document;

try
{
HTMLInputElement oUser = null, oPass = null;

oUser = (HTMLInputElement) myDoc.all.item("username", 0);
oPass = (HTMLInputElement) myDoc.all.item("password", 0);

if (oUser == null || oPass == null) return;

oUser.value = "username_value";
oPass.value = "password_value";

HTMLFormElement frm = (HTMLFormElement) myDoc.all.item("login", 0);
frm.submit();

this.Task = 1;
}
catch (Exception ex)
{
this.showInfo("test() error: " + ex.Message);
}
}


///
/// Example of using HTTP Post to download an Excel file.
///
private void getExcel() {
HttpWebResponse resp = null;
Stream stream;
string filename = this.downloadFolder + "/download.xls";

try
{
wr = (HttpWebRequest) WebRequest.Create(this.excel_url);
wr.Method = "POST";
wr.ContentType = "application/x-www-form-urlencoded";
wr.ContentLength = byteArray.Length;
wr.Timeout = 100000; // in ms. Set this bigger than the site timeout value.
MyUtil.appendLog("wr.contentlength: " + wr.ContentLength);

wr.CookieContainer = new CookieContainer();
wr.CookieContainer.SetCookies(new Uri(this.excel_url) ,
((mshtml.HTMLDocumentClass) this.axWebBrowser1.Document).cookie.ToString());
MyUtil.appendLog("cookie: " +
((mshtml.HTMLDocumentClass) this.axWebBrowser1.Document).cookie);

// Send post request
Stream dataStream = wr.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
resp = (HttpWebResponse) wr.GetResponse();
resp.Cookies = wr.CookieContainer.GetCookies(resp.ResponseUri);
MyUtil.appendLog("resp status: " + resp.StatusDescription);

stream = resp.GetResponseStream();

//MyUtil.appendLog("resp header: " + resp.ContentType );
// Header: usually 'txt/html'. here is 'application/vnd.ms-excel'
StreamReader reader = new StreamReader(stream);
try
{
MyUtil.saveFile(filename, reader.ReadToEnd());
this.downloadSucceed = true;
}
catch (Exception ex)
{
MyUtil.FileDelete(filename);
this.downloadSucceed = false;
}
finally
{
reader.Close();
}
}
catch (Exception ex)
{
this.downloadSucceed = false;
MyUtil.FileDelete(filename);
}
finally
{
if (resp != null) { resp.Close(); }
}
}

///
/// Another way of navigating website: use the axWebBrowser control.
///
this.axWebBrowser1.Navigate(url);

[1] The user32 SendInput windows API. The SendInput function synthesizes
keystrokes, mouse motions, and button clicks to the currently active window.
[2] Capturing binary download via code through axwebbrowser1.

Tuesday, July 20, 2010

Sams Teach Yourself TCP/IP in 24 Hours

Sams Teach Yourself TCP/IP in 24 Hours (4th Edition) - by Joe Casad, 2008, 456 pages. ISBN-10: 0672329964.

I caught this book in sight at Barns and Noble. It is a short book to read, to the point and clear on basic concepts. Short is good.

I. TCP/IP basics

II. TCP/IP Protocol system

2. Correspondence of TCP/IP model and OSI model.
TCP/IP OSI Relevant protocols
----------------------------------------------------------------------------------
Application layer A,P,S
Transport layer T TCP/UDP
Internet layer N IP, ARP, RARP, ICMP, router(RIP, OSPF etc.)
Network access layer D,P FTS, FDDI, PPP, 802.11, 802.3, 802.16

note: 802.3 - ethernet, 802.11 - wireless, 802.16 - winmax

3. Network access layer
- physical addressing.
- LAN - ethernet.
CSMA/CS (Carrier Sense Multiple Access with Collision Detect)
ethernet frame: preamble|dest addr|sr addr|length|data|FCS(CRC)

4. Internet layer
- IP, IP header
- IP addressing: class A(8/24), B(16/16), C(24/8), D, E
- ARP (Address Resolution Protocol)
- RARP (Reverse ARP)
- ICMP
- BGP (Border Gateway Protocol), RIP (Routing Information Protocol)

5. Subnetting & CIDR (Classless Inter-Domain Routing)
- subnet mask/host ID
- split and combine networks.

6. Transport layer
- TCP/UDP
- ports, sockets
- multiplexing, demultiplexing.
- TCP: stream, resequencing, flow control, precedence & security, graceful close.

7. Application layer
- use socket/port to communicate with transport layer.
- target of multiplexing/de-multiplexing

III. Networking with TCP/IP

8. Routing
- routing table
- IP forwarding
- Dynamic routing algorithm
- DV (Distance vector). e.g. RIP
- LS (Link state). e.g. OSPF (Open Shortest Path First)
LS is more popular than DV now.
- Complex network routing
1) core router - backbone network (GGP)
2) exterior router - on border of autonomous systems (EGP: e.g. BGP)
3) interior router - within autonomous system (IGP: OSPF/RIP)
- classless routing: CIDR.
- OSPF: implemented as routed on unix/linux, builds SPT (Shortest Path Tree)

10. Firewall
- DMZ (Demilitarized Zone)
- rules
- proxy service
- reverse proxy

11. Name resolution
- DNS (Domain Name Server)

IV. TCP/IP utilities.

V. TCP/IP and the internet

18. Email
- outgoing email: SMTP
- incoming email: POP3/IMAP

19. Streaming and casting
- stack:
RTP
UDP
Internet layer
Network Access layer

VI. Advanced topics

C Traps and Pitfalls

C Traps and Pitfalls - by Andrew Koenig, 1989, 160 pages. ISBN-10: 0201179288.

Andrew Koenig wrote a small reference manual on C programming based on his experience when he worked at AT&T lab. Since it received wide acceptance, he added more material and resulted in this book. It's highly recommended to any serious C programmers. Some contents are kind of outdated, such as those about problems of early day compilers. But many points are still ubiquitously applicable.

- Introduction

- Chapter 1. Lexical pitfalls
1.3 greedy principle in evaluating statement.
e.g. a --- b is: a-- - b,
y = x/*p is: y=x plus the start of a comment!
Should write as y = x / *p or y = x / (*p).
a +++++ b is: a++ ++ + b. This has compile error since a++ is not l-value.
Be careful, if a number starts with 0, it's an octal number.

- Chapter 2. Syntax pitfalls
2.1 Function declaration.
This casts address 0 as the pointer to function void f() and call it.
(* (void (*)()) 0)();
2.2 Operator precedence.
if (a == 'a' || b = 'b' || c == 'c') {} is equivalent to:
if ((a == 'a' || b) = ('b' || c == 'c')) {}
2.6 dangling else.
if (a)
if (b) b ++;
else { c ++; }
is equivalent to:
if (a) {
if (b) b ++;
else { c ++; }
}

Chapter 3. Semantic pitfalls
3.6 off-by-1 error - is the most prevalent.
One solution in C: 0-based C array, using asymmetric boundary.
e.g. x >= 16 && x < 38. 38-16 is exactly the size of the range.
3.9 Check overflow.
method 1: if ((unsigned) a + (unsigned) b > INT_MAX) // overflowed
method 2: if (a > INT_MAX - b) // overflowed

Chapter 4. Linking
lint.

Chapter 5. Library functions
5.1 int getchar() - return types does not match function, can cause problem.
5.2 I/O buffer.
setbuf(stdout, (char *) 0); // no buffer
5.4 errno
5.5 signal, longjmp

Chapter 6. Preprocessor
- macro
- use of -- or ++ can cause unexpected side effects in macro.
6.3 assert
#define assert(e) \
((void) ((e) || _assert_error(__FILE__, __LINE__)))

Chapter 7. Portability
7.5 >> and divide by 2. >> is faster and works correctly when var is positive.
e.g. replace "mid = (left + right) / 2" with "mid = (left + right) >> 1".
7.11 literal string can represent an array.
e.g. "0123456789"[n%10] is equivalent to: a[] = "0123456789"; a[n%10];
This is used in systems where 0-9 may not be consecutive.

Chapter 8. Suggestions and answers.
- Optimize binary search:
1) use >> instead of 1/2, 2) use pointer instead of array indexing.
- Little/big ending.
- getchar(), putchar() have both macro and function definitions. macro is faster.
- atol().

Appendix A
- printf. %p, %n, %06d is equivalent to %.6d in most cases.
- varargs
- stdarg

Author's suggestions on using C++:
- avoid pointer
- use library
- use class

Blog Archive

Followers