Code Listings
Chapter 14: Networking
IP Addresses:
IPAddress a1 = new IPAddress (new byte[] { 101, 102, 103, 104 }); IPAddress a2 = IPAddress.Parse ("101.102.103.104"); Console.WriteLine (a1.Equals (a2)); // True Console.WriteLine (a1.AddressFamily); // InterNetwork IPAddress a3 = IPAddress.Parse ("[3EA0:FFFF:198A:E4A3:4FF2:54fA:41BC:8D31]"); Console.WriteLine (a3.AddressFamily); // InterNetworkV6
IPAddress a = IPAddress.Parse ("101.102.103.104"); IPEndPoint ep = new IPEndPoint (a, 222); // Port 222 Console.WriteLine (ep.ToString()); // 101.102.103.104:222
URIs:
Uri info = new Uri ("http://www.domain.com:80/info/"); Uri page = new Uri ("http://www.domain.com/info/page.html"); Console.WriteLine (info.Host); // www.domain.com Console.WriteLine (info.Port); // 80 Console.WriteLine (page.Port); // 80 (Uri knows the default HTTP port) Console.WriteLine (info.IsBaseOf (page)); // True Uri relative = info.MakeRelativeUri (page); Console.WriteLine (relative.IsAbsoluteUri); // False Console.WriteLine (relative.ToString()); // page.html
Simple use of WebClient:
using (WebClient wc = new WebClient()) { wc.Proxy = null; wc.DownloadFile ("http://www.albahari.com/nutshell/code.html", "code.html"); } System.Diagnostics.Process.Start ("code.html");
Simple use of WebRequest / WebResponse:
WebRequest req = WebRequest.Create ("http://www.albahari.com/nutshell/code.html"); req.Proxy = null; using (WebResponse res = req.GetResponse()) using (Stream s = res.GetResponseStream()) using (StreamReader sr = new StreamReader(s)) File.WriteAllText ("code.html", sr.ReadToEnd()); System.Diagnostics.Process.Start ("code.html");
Proxies:
// Create a WebProxy with the proxy's IP address and port. You can // optionally set Credentials if the proxy needs a username/password. WebProxy p = new WebProxy ("192.178.10.49", 808); p.Credentials = new NetworkCredential ("username", "password"); // or: p.Credentials = new NetworkCredential ("username", "password", "domain"); using (WebClient wc = new WebClient()) { wc.Proxy = p; ... } // Same procedure with a WebRequest object: WebRequest req = WebRequest.Create ("..."); req.Proxy = p;
Authentication:
using (WebClient wc = new WebClient()) { wc.Proxy = null; wc.BaseAddress = "ftp://ftp.albahari.com/incoming/"; // Authenticate, then upload and download a file to the FTP server. // The same approach also works for HTTP and HTTPS. string username = "anonymous@albahari.com"; string password = ""; wc.Credentials = new NetworkCredential (username, password); wc.DownloadFile ("guestbook.txt", "guestbook.txt"); string data = "Hello from " + Environment.UserName + "!\r\n"; File.AppendAllText ("guestbook.txt", data); wc.UploadFile ("guestbook.txt", "guestbook.txt"); }
CredentialCache:
CredentialCache cache = new CredentialCache(); Uri prefix = new Uri ("http://exchange.mydomain.com"); cache.Add (prefix, "Digest", new NetworkCredential ("joe", "passwd")); cache.Add (prefix, "Negotiate", new NetworkCredential ("joe", "passwd")); WebClient wc = new WebClient(); wc.Credentials = cache; ...
Concurrency without asynchronous event methods:
using System; using System.Net; using System.Threading; class ThreadTest { static void Main() { new Thread (Download).Start(); Console.WriteLine ("I'm still here while the download's happening!"); Console.ReadLine(); } static void Download() { using (WebClient wc = new WebClient()) try { wc.Proxy = null; wc.DownloadFile ("http://www.oreilly.com", "oreilly.html"); Console.WriteLine ("Finished!"); } catch (Exception ex) { // Process exception... } } }
Exception handling with WebClient/WebRequest/WebResponse:
using (WebClient wc = new WebClient()) try { wc.Proxy = null; string s = wc.DownloadString ("http://www.albahari.com/notthere"); } catch (WebException ex) { if (ex.Status == WebExceptionStatus.NameResolutionFailure) Console.WriteLine ("Bad domain name"); else if (ex.Status == WebExceptionStatus.ProtocolError) { HttpWebResponse response = (HttpWebResponse) ex.Response; Console.WriteLine (response.StatusDescription); // "Not Found" if (response.StatusCode == HttpStatusCode.NotFound) Console.WriteLine ("Not there!"); // "Not there!" } else throw; }
HTTP headers:
using (WebClient wc = new WebClient()) { wc.Proxy = null; wc.Headers.Add ("CustomHeader", "JustPlaying/1.0"); wc.DownloadString ("http://www.oreilly.com"); foreach (string name in wc.ResponseHeaders.Keys) Console.WriteLine (name + "=" + wc.ResponseHeaders [name]); }
HTTP query strings:
using (WebClient wc = new WebClient()) { wc.Proxy = null; wc.QueryString.Add ("q", "WebClient"); // Search for "WebClient" wc.QueryString.Add ("hl", "fr"); // Display page in French wc.DownloadFile ("http://www.google.com/search", "results.html"); System.Diagnostics.Process.Start ("results.html"); }
Uploading form data with WebClient:
using (WebClient wc = new WebClient()) { wc.Proxy = null; var data = new System.Collections.Specialized.NameValueCollection(); data.Add ("searchtextbox", "webclient"); data.Add ("searchmode", "simple"); byte[] result = wc.UploadValues ("http://safari.oreilly.com/search", "POST", data); System.IO.File.WriteAllBytes ("SearchResults.html", result); System.Diagnostics.Process.Start ("SearchResults.html"); }
Uploading form data with WebRequest:
WebRequest req = WebRequest.Create ("http://safari.oreilly.com/search"); req.Proxy = null; req.Method = "POST"; req.ContentType = "application/x-www-form-urlencoded"; string reqString = "searchtextbox=webclient&searchmode=simple"; byte[] reqData = Encoding.UTF8.GetBytes (reqString); req.ContentLength = reqData.Length; using (Stream reqStream = req.GetRequestStream()) reqStream.Write (reqData, 0, reqData.Length); using (WebResponse res = req.GetResponse()) using (Stream resSteam = res.GetResponseStream()) using (StreamReader sr = new StreamReader (resSteam)) File.WriteAllText ("SearchResults.html", sr.ReadToEnd()); System.Diagnostics.Process.Start ("SearchResults.html");
Cookies:
CookieContainer cc = new CookieContainer(); var request = (HttpWebRequest) WebRequest.Create ("http://www.google.com"); request.Proxy = null; request.CookieContainer = cc; using (var response = (HttpWebResponse) request.GetResponse()) { foreach (Cookie c in response.Cookies) { Console.WriteLine (" Name: " + c.Name); Console.WriteLine (" Value: " + c.Value); Console.WriteLine (" Path: " + c.Path); Console.WriteLine (" Domain: " + c.Domain); } // Read response stream... }
Forms authentication:
string loginUri = "http://www.webshots.com/login"; string username = "username"; string password = "password"; string reqString = "username=" + username + "&password=" + password; byte[] requestData = Encoding.UTF8.GetBytes (reqString); CookieContainer cc = new CookieContainer(); var request = (HttpWebRequest)WebRequest.Create (loginUri); request.Proxy = null; request.CookieContainer = cc; request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; request.ContentLength = requestData.Length; using (Stream s = request.GetRequestStream()) s.Write (requestData, 0, requestData.Length); using (var response = (HttpWebResponse) request.GetResponse()) foreach (Cookie c in response.Cookies) Console.WriteLine (c.Name + " = " + c.Value);
SSL:
using System.Net; using System.Net.Security; using System.Security.Cryptography.X509Certificates; … static void ConfigureSSL() { ServicePointManager.ServerCertificateValidationCallback = CertChecker; } static bool CertChecker (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) { // Return true if you're happy with the certificate … }
Writing a simple HTTP server:
static void Main() { new System.Threading.Thread (Listen).Start(); // Run server in parallel. Thread.Sleep (500); // Wait half a second. using (WebClient wc = new WebClient()) // Make a client request. Console.WriteLine (wc.DownloadString ("http://localhost:51111/MyApp/Request.txt")); } static void Listen() { HttpListener listener = new HttpListener(); listener.Prefixes.Add ("http://localhost:51111/MyApp/"); // Listen on listener.Start(); // port 51111. // Wait for a client request: HttpListenerContext context = listener.GetContext(); // Respond to the request: string msg = "You asked for: " + context.Request.RawUrl; context.Response.ContentLength64 = Encoding.UTF8.GetByteCount (msg); context.Response.StatusCode = (int) HttpStatusCode.OK; using (Stream s = context.Response.OutputStream) using (StreamWriter writer = new StreamWriter (s)) writer.Write (msg); listener.Stop(); }
Writing a blocking pooled HTTP server:
using System; using System.IO; using System.Net; using System.Text; using System.Threading; class WebServer { HttpListener _listener; string _baseFolder; // Your web page folder. public WebServer (string uriPrefix, string baseFolder) { System.Threading.ThreadPool.SetMaxThreads (50, 1000); System.Threading.ThreadPool.SetMinThreads (50, 50); _listener = new HttpListener(); _listener.Prefixes.Add (uriPrefix); _baseFolder = baseFolder; } public void Start() // Run this on a separate thread, as { // we did before. _listener.Start(); while (true) try { HttpListenerContext request = _listener.GetContext(); ThreadPool.QueueUserWorkItem (ProcessRequest, request); } catch (HttpListenerException) { break; } // Listener stopped. catch (InvalidOperationException) { break; } // Listener stopped. } public void Stop() { _listener.Stop(); } void ProcessRequest (object listenerContext) { try { var context = (HttpListenerContext) listenerContext; string filename = Path.GetFileName (context.Request.RawUrl); string path = Path.Combine (_baseFolder, filename); byte[] msg; if (!File.Exists (path)) { context.Response.StatusCode = (int) HttpStatusCode.NotFound; msg = Encoding.UTF8.GetBytes ("Sorry, that page does not exist"); } else { context.Response.StatusCode = (int) HttpStatusCode.OK; msg = File.ReadAllBytes (path); } context.Response.ContentLength64 = msg.Length; using (Stream s = context.Response.OutputStream) s.Write (msg, 0, msg.Length); } catch (Exception ex) { Console.WriteLine ("Request error: " + ex); } } }
static void Main() { // Listen on the default port (80), serving files in e:\mydocs\webroot: var server = new WebServer ("http://localhost/", @"e:\mydocs\webroot"); // Start the server on a parallel thread: new System.Threading.Thread (server.Start).Start(); Console.WriteLine ("Server running... press Enter to stop"); Console.ReadLine(); server.Stop(); }
Using FTP:
using (WebClient wc = new WebClient()) { wc.Proxy = null; wc.Credentials = new NetworkCredential ("anonymous@albahari.com", ""); wc.BaseAddress = "ftp://ftp.albahari.com/incoming/"; wc.UploadString ("tempfile.txt", "hello!"); Console.WriteLine (wc.DownloadString ("tempfile.txt")); // hello! }
FTP ListDirectory:
var req = (FtpWebRequest) WebRequest.Create ( "ftp://ftp.albahari.com/incoming"); req.Proxy = null; req.Credentials = new NetworkCredential ("anonymous@albahari.com", ""); req.Method = WebRequestMethods.Ftp.ListDirectory; using (WebResponse resp = req.GetResponse()) using (StreamReader reader = new StreamReader (resp.GetResponseStream()) ) Console.WriteLine (reader.ReadToEnd());
FTP GetFileSize:
var req = (FtpWebRequest) WebRequest.Create ( "ftp://ftp.albahari.com/incoming/tempfile.txt"); req.Proxy = null; req.Credentials = new NetworkCredential ("anonymous@albahari.com", ""); req.Method = WebRequestMethods.Ftp.GetFileSize; using (WebResponse resp = req.GetResponse()) Console.WriteLine (resp.ContentLength); // 6
FTP LastModified:
req.Method = WebRequestMethods.Ftp.GetDateTimestamp; using (var resp = (FtpWebResponse) req.GetResponse() ) Console.WriteLine (resp.LastModified);
FTP Rename:
var req = (FtpWebRequest) WebRequest.Create ( "ftp://ftp.albahari.com/incoming/tempfile.txt"); req.Proxy = null; req.Credentials = new NetworkCredential ("anonymous@albahari.com", ""); req.Method = WebRequestMethods.Ftp.Rename; req.RenameTo = "deleteme.txt"; req.GetResponse().Close(); // Perform the rename
FTP DeleteFile:
var req = (FtpWebRequest) WebRequest.Create ( "ftp://ftp.albahari.com/incoming/deleteme.txt"); req.Proxy = null; req.Credentials = new NetworkCredential ("anonymous@albahari.com", ""); req.Method = WebRequestMethods.Ftp.DeleteFile; req.GetResponse().Close(); // Perform the deletion
Sending Mail with SmtpClient:
SmtpClient client = new SmtpClient(); client.Host = "mail.myisp.net"; client.Send ("from@adomain.com", "to@adomain.com", "subject", "body");
Mail attachments:
SmtpClient client = new SmtpClient(); client.Host = "mail.myisp.net"; MailMessage mm = new MailMessage(); mm.Sender = new MailAddress ("kay@domain.com", "Kay"); mm.From = new MailAddress ("kay@domain.com", "Kay"); mm.To.Add (new MailAddress ("bob@domain.com", "Bob")); mm.CC.Add (new MailAddress ("dan@domain.com", "Dan")); mm.Subject = "Hello!"; mm.Body = "Hi there. Here's the photo!"; mm.IsBodyHtml = false; mm.Priority = MailPriority.High; Attachment a = new Attachment ("photo.jpg", System.Net.Mime.MediaTypeNames.Image.Jpeg); mm.Attachments.Add (a); client.Send (mm);
TCP ping-pong:
using System; using System.IO; using System.Net; using System.Net.Sockets; using System.Threading; class TcpDemo { static void Main() { new Thread (Server).Start(); // Run server method concurrently. Thread.Sleep (500); // Give server time to start. Client(); } static void Client() { using (TcpClient client = new TcpClient ("localhost", 51111)) using (NetworkStream n = client.GetStream()) { BinaryWriter w = new BinaryWriter (n); w.Write ("Hello"); w.Flush(); Console.WriteLine (new BinaryReader (n).ReadString()); } } static void Server() // Handles a single client request, then exits. { TcpListener listener = new TcpListener (IPAddress.Any, 51111); listener.Start(); using (TcpClient c = listener.AcceptTcpClient()) using (NetworkStream n = c.GetStream()) { string msg = new BinaryReader (n).ReadString(); BinaryWriter w = new BinaryWriter (n); w.Write (msg + " right back!"); w.Flush(); // Must call Flush because we're not } // disposing the writer. listener.Stop(); } }
Receiving POP3 mail:
static void Receive() { using (TcpClient client = new TcpClient ("mail.isp.com ", 110)) using (NetworkStream n = client.GetStream()) { ReadLine (n); // Read the welcome message. SendCommand (n, "USER username"); SendCommand (n, "PASS password"); SendCommand (n, "LIST"); // Retrieve message IDs List<int> messageIDs = new List<int>(); while (true) { string line = ReadLine (n); // e.g. "1 1876" if (line == ".") break; messageIDs.Add (int.Parse (line.Split (' ')[0] )); // Message ID } foreach (int id in messageIDs) // Retrieve each message. { SendCommand (n, "RETR " + id); string randomFile = Guid.NewGuid().ToString() + ".eml"; using (StreamWriter writer = File.CreateText (randomFile)) while (true) { string line = ReadLine (n); // Read next line of message. if (line == ".") break; // Single dot = end of message. if (line == "..") line = "."; // "Escape out" double dot. writer.WriteLine (line); // Write to output file. } SendCommand (n, "DELE " + id); // Delete message off server. } SendCommand (n, "QUIT"); } } static string ReadLine (Stream s) { List<byte> lineBuffer = new List<byte>(); while (true) { int b = s.ReadByte(); if (b == 10 || b < 0) break; if (b != 13) lineBuffer.Add ((byte)b); } return Encoding.UTF8.GetString (lineBuffer.ToArray()); } static void SendCommand (Stream stream, string line) { byte[] data = Encoding.UTF8.GetBytes (line + "\r\n"); stream.Write (data, 0, data.Length); string response = ReadLine (stream); if (!response.StartsWith ("+OK")) throw new Exception ("POP Error: " + response); }
© 2007, O'Reilly Media, Inc. All rights reserved