Out-of-the-box networking support in the .NET FCL enables developers to develop network-aware and network-centric distributed applications. As noted earlier, networking is a low-level distribution mechanism available in the .NET Framework. Capabilities such as .NET Remoting and ASP.NET Web services further abstract the use of sockets and provide a higher level of developer abstraction, ease-of-use, and management for developing distributed applications. Key classes in the System.Net and System.Net.Socket namespaces include the following:
Basic TCP ClientAs the first example of using the networking classes in the .NET Framework (shown in Listing 4.15), you will use the TcpClient class to connect with a Web resource (Port 80). Listing 4.15 Basic TCP Clientusing System; using System.IO; using System.Net; using System.Net.Sockets; using System.Text; public class Yahoo2 { public static void Main() { String ticker = "MSFT"; String url = "/d/quotes.csv?s="+ticker+"&f=sl1d1t1c1ohgv&e=.csv"; TcpClient sock = new TcpClient("finance.yahoo.com",80); Stream stream = sock.GetStream(); Byte[] req = Encoding.ASCII.GetBytes("GET "+url+" HTTP/1.0\n\n"); stream.Write(req,0,req.Length); stream.Flush(); StreamReader inp = new StreamReader(stream); String line; while ((line = inp.ReadLine())!=null) { Console.WriteLine(line); } inp.Close(); } } Running the Yahoo2 example (using TcpClient) should provide the current stock price information for MSFT with the basic HTTP headers. HTTP/1.1 200 OK Date: Thu, 04 Sep 2003 17:19:23 GMT P3P: policyref="http://p3p.yahoo.com/w3c/p3p.xml", CP="..." Cache-Control: private Connection: close Content-Type: application/octet-stream "MSFT",... In Listing 4.16, you will utilize the abstracted WebRequest to perform the same operation. Notice the simplicity achieved with the following application: Listing 4.16 Using WebRequest Classusing System; using System.Net; using System.IO; public class Yahoo { public static void Main() { String ticker = "MSFT"; WebRequest req = WebRequest.Create(http://finance.yahoo.com +"/d/quotes.csv?s="+ticker+"&f=sl1d1t1c1ohgv&e=.csv"); StreamReader inp = new StreamReader( req.GetResponse().GetResponseStream()); String line; while ((line = inp.ReadLine())!=null) { Console.WriteLine(line); } inp.Close(); } } A similar output is obtained running the modified Yahoo example. However, the HTTP headers won't be printed this time. So far what you have created using the networking classes are networking clients. Next, you will build a networking service that can provide access to other TCP clients (Listing 4.17). You will build a basic date server, which will provide the current date information when connected with port 777. Note the usage of multithreading to provide a service that can service multiple client requests at the same time. Listing 4.17 Creating a Multithreaded TCP Serverusing System; using System.Net; using System.Net.Sockets; using System.IO; using System.Threading; public class DateServer { private String name; private int port; public static void Main() { DateServer ds = new DateServer("Hitesh's Date Server",777); ds.Start(); } public DateServer(String name, int port) { this.name = name; this.port = port; } public void Start() { TcpListener tcpListener = new TcpListener( IPAddress.Parse("127.0.0.1"),port); tcpListener.Start(); Console.WriteLine("Date Server Started"); while (true) { TcpClient client = tcpListener.AcceptTcpClient(); DateThread dt = new DateThread(client,name); Thread thread = new Thread(new ThreadStart(dt.Run)); thread.Start(); } } } public class DateThread { private TcpClient client; private String name; public DateThread(TcpClient client, String name) { this.client = client; this.name = name; } public void Run() { try { Thread.Sleep(5000); StreamWriter output = new StreamWriter(client.GetStream()); DateTime now = DateTime.Now; output.WriteLine(name+":"+now.ToString()); output.Flush(); output.Close(); client.Close(); } catch (Exception ex) { Console.WriteLine(ex.StackTrace); } } } To connect with your newly developed networked data service, you need to implement a basic client (Listing 4.18) that connects to the service and then echoes back the response received. Listing 4.18 Network Client to Read Date from Date Serverusing System; using System.IO; using System.Net; using System.Net.Sockets; using System.Text; public class DateClient { public static void Main() { TcpClient sock = new TcpClient("localhost",777); Stream stream = sock.GetStream(); StreamReader inp = new StreamReader(stream); String line; while ((line = inp.ReadLine())!=null) { Console.WriteLine(line); } sock.Close(); } } Next you will combine the two network application applications to implement a multithreaded quote server that, in turn , uses a WebRequest to communicate with the Yahoo HTTP-based "Get Stock Quotes" Web page (Listing 4.19). Listing 4.19 Multithreaded Quote Serverusing System; using System.Net; using System.Net.Sockets; using System.IO; using System.Threading; public class QuoteServer { private String name; private int port; public static void Main() { QuoteServer ds = new QuoteServer("Hitesh's Quote Server",888); ds.Start(); } public QuoteServer(String name, int port) { this.name = name; this.port = port; } public void Start() { TcpListener tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"),port); tcpListener.Start(); Console.WriteLine("Quote Server Started"); while (true) { TcpClient client = tcpListener.AcceptTcpClient(); QuoteThread dt = new QuoteThread(client,name); Thread thread = new Thread(new ThreadStart(dt.Run)); thread.Start(); } } } public class QuoteThread { private TcpClient client; private String name; public QuoteThread(TcpClient client, String name) { this.client = client; this.name = name; } public void Run() { try { Stream stream = client.GetStream(); byte[] bytes = new Byte[256]; int inbytes = stream.Read(bytes,0,bytes.Length); String ticker = System.Text.Encoding.ASCII.GetString(bytes, 0, inbytes); WebRequest req = WebRequest.Create( "http://finance.yahoo.com/d/quotes.csv?s=" +ticker+"&f=sl1d1t1c1ohgv&e=.csv"); StreamReader inp = new StreamReader( req.GetResponse().GetResponseStream()); String line = inp.ReadLine(); byte[] outbytes = System.Text.Encoding.ASCII.GetBytes(line); stream.Write(outbytes,0,outbytes.Length); client.Close(); } catch (Exception ex) { Console.WriteLine(ex.StackTrace); } } } Listing 4.20 shows a modified client for your own quote server: Listing 4.20 Networking Client for Quote Server in Listing 4.18using System; using System.IO; using System.Net; using System.Net.Sockets; using System.Text; public class QuoteClient { public static void Main(String[] args) { TcpClient sock = new TcpClient("localhost",888); Stream stream = sock.GetStream(); String ticker = args[0]; byte[] bytes = System.Text.Encoding.ASCII.GetBytes(ticker); stream.Write(bytes,0,bytes.Length); byte[] outbytes = new byte[1024]; int count = stream.Read(outbytes,0,outbytes.Length); sock.Close(); String quote = System.Text.Encoding.ASCII.GetString(outbytes,0,count); Console.WriteLine(quote); } }
|