<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;C0AFSXc5fCp7ImA9WhRVGEg.&quot;"><id>tag:blogger.com,1999:blog-6013019333081665053</id><updated>2012-01-17T17:55:18.924-08:00</updated><category term="Network" /><category term="NTLM" /><category term="Microsoft" /><category term="System.Net" /><category term="DataOutputStream" /><category term="Lucene" /><category term="Exchange" /><category term="apple" /><category term="Logging" /><category term="ICMP" /><category term="ByteBuffer" /><category term="Tracing" /><category term="Java" /><category term="Search" /><category term="WWW HTTPS" /><category term="retina display" /><category term="iphone" /><category term="Unified Messaging" /><category term="Socket" /><category term="Debugging" /><category term="Authentication" /><category term="RMI JMX" /><category term="SendFile" /><category term="BinaryReader" /><category term="Tracing WebClient Multipart MIME Form Post FileUpload" /><category term="DataInputStream" /><category term="Miscellaneous" /><category term="BinaryWriter" /><category term="TransmitFile" /><category term="HttpWebRequest" /><title>Feroze's musings on Technology</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://ferozedaud.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://ferozedaud.blogspot.com/" /><author><name>Feroze Daud</name><uri>https://profiles.google.com/106931323736171420480</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-htqG4D1zj34/AAAAAAAAAAI/AAAAAAAAAJM/o1zOCSZPA3c/s512-c/photo.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>23</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/FerozesMusingsOnTechnology" /><feedburner:info uri="ferozesmusingsontechnology" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="license" type="text/html" href="http://creativecommons.org/licenses/by/2.0/" /><logo>http://creativecommons.org/images/public/somerights20.gif</logo><entry gd:etag="W/&quot;C0YCR3c6fSp7ImA9WhdWEUQ.&quot;"><id>tag:blogger.com,1999:blog-6013019333081665053.post-1105081392491740182</id><published>2011-09-04T19:52:00.000-07:00</published><updated>2011-09-04T19:52:46.915-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-04T19:52:46.915-07:00</app:edited><title>How to share NTLM connection across HttpWebRequest objects</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
When writing an application that talks to a server using NTLM authentication, HttpWebRequest does a three legged authentication handshake that looks as follows:

&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Client&lt;/td&gt;
&lt;td&gt;Server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET / HTTP/1.1&lt;/td&gt;
&lt;td&gt;HTTP/1.1 401 Access Denied&lt;br /&gt;
Connection: close&lt;br /&gt;
WWW-Authenticate: NTLM &amp;lt;token&amp;gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GET / HTTP/1.1&lt;br /&gt;
Authorization: NTLM &amp;lt;token1&amp;gt;
&lt;/td&gt;
&lt;td&gt;HTTP/1.1 401 Access Denied&lt;br /&gt;
Connection: close&lt;br /&gt;
WWW-Authenticate: NTLM NTLM &amp;lt;token&amp;gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;GET / HTTP/1.1&lt;br /&gt;
Authorization: NTLM &amp;lt;token2&amp;gt;
&lt;/td&gt;
&lt;td&gt;HTTP/1.1 200 OK&lt;br /&gt;
&lt;em&gt;Connection: close&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
As you can see, by default, HttpWebRequest does not share connections. The reason is that NTLM is a connection authentication protocol, and not a request authentication protocol like BASIC or DIGEST. 
&lt;br /&gt;
&lt;br /&gt;
In other words, once an NTLM handshake succeeds, the NTLM credentials stick with the connection. So, if you have a situation (for eg, a web server talking to another webserver using NTLM auth) where there are multiple users with different credentials accessing the front-end server, there is a high risk that an authenticated connection for one user might get used by another user due to connection pooling.
&lt;br /&gt;
&lt;br /&gt;
In order to force HttpWebRequest to share NTLM connections, you can do the following:
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.unsafeauthenticatedconnectionsharing.aspx"&gt;UnsafeAuthenticatedConnectionSharing&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
Use &lt;a href="http://msdn.microsoft.com/en-us/library/6y3d5dts.aspx"&gt;ConnectionGroupName&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
Setting UnsafeAuthenticatedConnectionSharing will cause all NTLM connections to the same host to be shared.
&lt;br /&gt;
&lt;br /&gt;
By setting ConnectionGroupName, you can cause connections to be shared only selectively. In this case, all requests having the same ConnectionGroupName will share connections. You can use this mechanism if you are on the middle-tier scenario.



&lt;br /&gt;
&lt;br /&gt;
Related:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://ferozedaud.blogspot.com/2009/11/systemnet-links-and-howtos.html"&gt;System.NET Links and How To's&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://ferozedaud.blogspot.com/2009/08/tracing-with-systemnet.html"&gt;Tracing with System.Net&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://ferozedaud.blogspot.com/2009/09/case-of-multiple-ntlm-challenges-with.html"&gt;The case of multiple NTLM challenges with IIS7&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6013019333081665053-1105081392491740182?l=ferozedaud.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/PBfD3z7nH1xqBUup00lKl-bpV_8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PBfD3z7nH1xqBUup00lKl-bpV_8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/PBfD3z7nH1xqBUup00lKl-bpV_8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PBfD3z7nH1xqBUup00lKl-bpV_8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FerozesMusingsOnTechnology/~4/LBAsYN3JLFU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ferozedaud.blogspot.com/feeds/1105081392491740182/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://ferozedaud.blogspot.com/2011/09/how-to-share-ntlm-connection-across.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/1105081392491740182?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/1105081392491740182?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/FerozesMusingsOnTechnology/~3/LBAsYN3JLFU/how-to-share-ntlm-connection-across.html" title="How to share NTLM connection across HttpWebRequest objects" /><author><name>Feroze Daud</name><uri>https://profiles.google.com/106931323736171420480</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-htqG4D1zj34/AAAAAAAAAAI/AAAAAAAAAJM/o1zOCSZPA3c/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://ferozedaud.blogspot.com/2011/09/how-to-share-ntlm-connection-across.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEADQXo5eip7ImA9WhdRGU4.&quot;"><id>tag:blogger.com,1999:blog-6013019333081665053.post-1876106077918510802</id><published>2011-08-09T16:32:00.000-07:00</published><updated>2011-08-09T16:32:50.422-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-09T16:32:50.422-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="RMI JMX" /><title>Diagnosing RMI Exception: java.rmi.ConnectException: Connection refused to host: 127.0.0.1</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;I have a service that runs on Linux under JBOSS. This service uses JMX (RMI) to talk to a windows box running a java service.&lt;br /&gt;
&lt;br /&gt;
Everything was working ok, until both the Linux and Windows boxes were moved to a different subnet. Then, they started failing with the following exception:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;Caused by: java.rmi.ConnectException: Connection refused to host: 127.0.0.1; nested exception is: &lt;br /&gt;
java.net.ConnectException: Connection refused&lt;br /&gt;
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:601)&lt;br /&gt;
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:198)&lt;br /&gt;
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:184)&lt;br /&gt;
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:110)&lt;br /&gt;
at javax.management.remote.rmi.RMIServerImpl_Stub.newClient(Unknown Source)&lt;br /&gt;
at javax.management.remote.rmi.RMIConnector.getConnection(RMIConnector.java:2312)&lt;br /&gt;
at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:277)&lt;br /&gt;
at javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java:248)&lt;br /&gt;
at com.zillow.core.jmx.ZillowJMXConnectorFactory.connect(ZillowJMXConnectorFactory.java:127)&lt;br /&gt;
at com.zillow.core.jmx.ZillowJMXConnectorFactory.connect(ZillowJMXConnectorFactory.java:53)&lt;br /&gt;
at com.zillow.bcpserver.BCPServerProxy.afterPropertiesSet(BCPServerProxy.java:123)&lt;br /&gt;
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1369)&lt;br /&gt;
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1335)&lt;br /&gt;
... 142 more&lt;br /&gt;
Caused by: java.net.ConnectException: Connection refused&lt;br /&gt;
at java.net.PlainSocketImpl.socketConnect(Native Method)&lt;br /&gt;
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)&lt;br /&gt;
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)&lt;br /&gt;
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)&lt;br /&gt;
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:366)&lt;br /&gt;
at java.net.Socket.connect(Socket.java:519)&lt;br /&gt;
at java.net.Socket.connect(Socket.java:469)&lt;br /&gt;
at java.net.Socket.&lt;init&gt;(Socket.java:366)&lt;br /&gt;
at java.net.Socket.&lt;init&gt;(Socket.java:180)&lt;br /&gt;
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:22)&lt;br /&gt;
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:128)&lt;br /&gt;
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:595)&lt;br /&gt;
... 154 more&lt;br /&gt;
&lt;br /&gt;
&lt;/init&gt;&lt;/init&gt;&lt;/blockquote&gt;&lt;br /&gt;
I searched for this exception in the search engines, and the only thing I found was people saying that if the local box (i.e linux) did not have a correct IP address for localhost, it would send the 127.0.0.1 address as the "ContactMe" endpoint to the remote destination, and that would fail.&lt;br /&gt;
&lt;br /&gt;
For example, the following links explained that issue:&lt;br /&gt;
&lt;br /&gt;
http://forum.springsource.org/showthread.php?33711-RMI-invocation-attempts-connecting-to-127.0.0.1&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
However, in my case, that turned out not to be the problem. My Linux boxes (even after the move) had the correct hostname, and the `hostname` command was giving back the correct hostname (and not 127.0.0.1 or localhost).&lt;br /&gt;
&lt;br /&gt;
At this point, there was no more information available through the search engines to diagnose the problem.&lt;br /&gt;
&lt;br /&gt;
So, I decided to debug it myself. I first restarted the service, and used TCPDUMP to do a network sniff on the linux box.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-D4cPLYjoUdo/TkHBaCBOlMI/AAAAAAAAAHs/mqjjYTG3Yww/s1600/pict1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/-D4cPLYjoUdo/TkHBaCBOlMI/AAAAAAAAAHs/mqjjYTG3Yww/s1600/pict1.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;
Here, .175 is the Linux box, and .45 is the windows box.&lt;br /&gt;
&lt;br /&gt;
The following is the packet disassembly of the JRMI/ReturnData response being sent by the Windows box to the Linux box.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-PSt0jEcqt6Y/TkHCLUn86iI/AAAAAAAAAH0/HxNd5ATbzUU/s1600/pict2.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="245" width="400" src="http://1.bp.blogspot.com/-PSt0jEcqt6Y/TkHCLUn86iI/AAAAAAAAAH0/HxNd5ATbzUU/s400/pict2.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
As you can see, the Windows server is sending back "127.0.0.1" as the CallMe endpoint to the Linux box. The linux box tries to connect to port 1099 on 127.0.0.1 and fails.&lt;br /&gt;
&lt;br /&gt;
Since the machines had been moved to different networks, it is possible that the java service might have lost their IP address and network registration settings.&lt;br /&gt;
&lt;br /&gt;
So, I restarted the java service on the windows box. And viola!, that fixed the problem.&lt;br /&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6013019333081665053-1876106077918510802?l=ferozedaud.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/4y2rYWb7BSgaQlO2TWS3fxhyIEs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4y2rYWb7BSgaQlO2TWS3fxhyIEs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/4y2rYWb7BSgaQlO2TWS3fxhyIEs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4y2rYWb7BSgaQlO2TWS3fxhyIEs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FerozesMusingsOnTechnology/~4/JjFM4GIrspc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ferozedaud.blogspot.com/feeds/1876106077918510802/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://ferozedaud.blogspot.com/2011/08/diagnosing-rmi-exception.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/1876106077918510802?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/1876106077918510802?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/FerozesMusingsOnTechnology/~3/JjFM4GIrspc/diagnosing-rmi-exception.html" title="Diagnosing RMI Exception: java.rmi.ConnectException: Connection refused to host: 127.0.0.1" /><author><name>Feroze Daud</name><uri>https://profiles.google.com/106931323736171420480</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-htqG4D1zj34/AAAAAAAAAAI/AAAAAAAAAJM/o1zOCSZPA3c/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-D4cPLYjoUdo/TkHBaCBOlMI/AAAAAAAAAHs/mqjjYTG3Yww/s72-c/pict1.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://ferozedaud.blogspot.com/2011/08/diagnosing-rmi-exception.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE4NQXs_fCp7ImA9WhZTGEw.&quot;"><id>tag:blogger.com,1999:blog-6013019333081665053.post-2926323520134867550</id><published>2011-03-22T09:56:00.000-07:00</published><updated>2011-03-22T09:56:30.544-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-22T09:56:30.544-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="WWW HTTPS" /><title>Why isn't HTTPS used more on the web?</title><content type="html">Ars Technica has a great article giving the reasons &lt;a href="http://arstechnica.com/web/news/2011/03/https-is-more-secure-so-why-isnt-the-web-using-it.ars"&gt;why HTTPS is not used more on the Web.&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
The summary is as follows:&lt;br /&gt;
&lt;br /&gt;
1) HTTPS adds some latency to initial connection establishment.&lt;br /&gt;
2) HTTPS documents cannot be cached by the browser. While this is not a big issue when the client and server are on the same continents, &lt;br /&gt;
3) HTTPS websites cannot be virtual hosts on the same server, and this causes addition in operation costs.&lt;br /&gt;
&lt;br /&gt;
It goes on to add that while these are practical reasons why HTTPS isn't widely deployed, the practical hurdles will fall away eventually leading to a wider adoption of HTTPS.&lt;br /&gt;
&lt;br /&gt;
&lt;iframe src="http://rcm.amazon.com/e/cm?t=ferozesmusings-20&amp;o=1&amp;p=8&amp;l=bpl&amp;asins=0201615983&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr" style="align:left;padding-top:5px;width:131px;height:245px;padding-right:10px;"align="left" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6013019333081665053-2926323520134867550?l=ferozedaud.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/C4d6uYHT9RIaIX5lwyHnTiNytTM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/C4d6uYHT9RIaIX5lwyHnTiNytTM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/C4d6uYHT9RIaIX5lwyHnTiNytTM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/C4d6uYHT9RIaIX5lwyHnTiNytTM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FerozesMusingsOnTechnology/~4/_2mxrhSrLio" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ferozedaud.blogspot.com/feeds/2926323520134867550/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://ferozedaud.blogspot.com/2011/03/why-isnt-https-used-more-on-web.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/2926323520134867550?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/2926323520134867550?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/FerozesMusingsOnTechnology/~3/_2mxrhSrLio/why-isnt-https-used-more-on-web.html" title="Why isn't HTTPS used more on the web?" /><author><name>Feroze Daud</name><uri>https://profiles.google.com/106931323736171420480</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-htqG4D1zj34/AAAAAAAAAAI/AAAAAAAAAJM/o1zOCSZPA3c/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://ferozedaud.blogspot.com/2011/03/why-isnt-https-used-more-on-web.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0ACQns-fSp7ImA9WxFUFU0.&quot;"><id>tag:blogger.com,1999:blog-6013019333081665053.post-6628289847621383384</id><published>2010-06-25T15:42:00.000-07:00</published><updated>2010-06-25T15:42:43.555-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-25T15:42:43.555-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="retina display" /><category scheme="http://www.blogger.com/atom/ns#" term="iphone" /><category scheme="http://www.blogger.com/atom/ns#" term="apple" /><title>Via JonesBlog - Apples Retina Display</title><content type="html">Brian Jones analyzes Apple's claim that the Iphone4's display resolution is better than a human eye. Interesting reading.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6013019333081665053-6628289847621383384?l=ferozedaud.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/MR0EoETRTuZ7aJ5d3ZxDJtt9SzQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MR0EoETRTuZ7aJ5d3ZxDJtt9SzQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/MR0EoETRTuZ7aJ5d3ZxDJtt9SzQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MR0EoETRTuZ7aJ5d3ZxDJtt9SzQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FerozesMusingsOnTechnology/~4/66MXa4NkeIg" height="1" width="1"/&gt;</content><link rel="related" href="http://prometheus.med.utah.edu/~bwjones/2010/06/apple-retina-display/" title="Via JonesBlog - Apples Retina Display" /><link rel="replies" type="application/atom+xml" href="http://ferozedaud.blogspot.com/feeds/6628289847621383384/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://ferozedaud.blogspot.com/2010/06/via-jonesblog-apples-retina-display.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/6628289847621383384?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/6628289847621383384?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/FerozesMusingsOnTechnology/~3/66MXa4NkeIg/via-jonesblog-apples-retina-display.html" title="Via JonesBlog - Apples Retina Display" /><author><name>Feroze Daud</name><uri>https://profiles.google.com/106931323736171420480</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-htqG4D1zj34/AAAAAAAAAAI/AAAAAAAAAJM/o1zOCSZPA3c/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://ferozedaud.blogspot.com/2010/06/via-jonesblog-apples-retina-display.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEICRX44cCp7ImA9Wx5UGU0.&quot;"><id>tag:blogger.com,1999:blog-6013019333081665053.post-1885982241824977710</id><published>2010-03-21T22:58:00.000-07:00</published><updated>2010-10-23T23:42:44.038-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-23T23:42:44.038-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Tracing WebClient Multipart MIME Form Post FileUpload" /><category scheme="http://www.blogger.com/atom/ns#" term="System.Net" /><category scheme="http://www.blogger.com/atom/ns#" term="HttpWebRequest" /><title>Multipart Form Upload Helper</title><content type="html">&lt;span style="font-size: large;"&gt;&lt;br /&gt;
Implementing Multipart-MIME upload helper using WebClient&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;&lt;/div&gt;&lt;br /&gt;
The &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.webclient.aspx"&gt;WebClient&lt;/a&gt; class is a higher level abstraction on top of HttpWebRequest, that abstracts away the common tasks of uploading files, as well as doing Form Posts to HTTP servers. However, it does not provide an easy way to do multipart form uploads.&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;&lt;/div&gt;&lt;a href="http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2"&gt;Multipart form upload &lt;/a&gt;is defined by the W3C specification. &lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;&lt;/div&gt;&lt;span style="font-size: large;"&gt;Multipart HTML Form Design&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;&lt;/div&gt;Let us start off by designing the HTML Form that will be the target of the multipart upload. As per the HTML spec, the form should have an &lt;b&gt;enctype&lt;/b&gt; attribute set to "multipart/form-data". Also, we are going to have a File input control embedded in the form.&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;&lt;/div&gt;&lt;pre class="vb" name="code"&gt;&lt;form action="form.aspx" enctype="multipart/form-data" method="post" runat="server"&gt;Your name: &lt;input name="fname" /&gt;
Your id: &lt;input name="id" /&gt;

What files are you sending? 

&lt;input id="pics1" name="pics1" runat="server" type="file" /&gt;

&lt;input id="pics2" name="pics2" runat="server" type="file" /&gt;

&lt;input type="submit" /&gt;

&lt;/form&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;div&gt;&lt;span style="font-size: large;"&gt;MIME Part Requirements&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
In a multipart form upload, each mime part begins with some MIME headers. The following headers are mandatory:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Content-Disposition header&lt;/li&gt;
&lt;li&gt;A name attribute that specifies the name of the corresponding control from the HTML form.&lt;/li&gt;
&lt;/ul&gt;For eg, in the form above, if I specify "John" for the&amp;nbsp;name, and "1" for the ID, then I will have the following in the MIME upload&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;--BD37EC1 &lt;br /&gt;
Content-Disposition: form-data; name="fname";&lt;br /&gt;
&lt;br /&gt;
john&lt;br /&gt;
--BD37EC1&lt;br /&gt;
Content-Disposition: form-data; name="id";&lt;/blockquote&gt;&lt;blockquote&gt;acme&lt;br /&gt;
--BD37EC1&lt;/blockquote&gt;Ideally, our helper class should be able to write out the boundaries itself, and delegate the task of writing out the headers to each MIME part that is part of the upload.&lt;br /&gt;
&lt;br /&gt;
Our multipart form has two kinds of controls: normal Text input as well as FILE input controls. Therefore, our helper class needs to support both of these types of MIME parts.&lt;br /&gt;
&lt;br /&gt;
Let us start off by thinking about the layour of the MIME part classes.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;MIME Part Design&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
As discussed, we are going to have two types of MIME parts - a normal FORM upload type where we want to specify Name/Value pairs, as well as a FILE part where we want to embed the contents of a file. &lt;br /&gt;
&lt;br /&gt;
In the previous section we saw the basic requirements of a MIME part. It has to have a "Content-Disposition" header. In addition to this, a MIME part that contains file contents should also have a "Content-Type" header.&lt;br /&gt;
&lt;br /&gt;
With this, we can now write out the layout of the base class for these two MIME parts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;/// &lt;summary&gt;
    /// MimePart
    /// Abstract class for all MimeParts
    /// &lt;/summary&gt;
    abstract class MimePart
    {
        public string Name { get; set; }

        public abstract string ContentDisposition { get; }

        public abstract string ContentType { get; }

        public abstract void CopyTo(Stream stream);

        public String Boundary
        {
            get;
            set;
        }
    }
&lt;/pre&gt;&lt;br /&gt;
This is a good abstraction of a MIME part. Derived classes can define the Content-Type and Content-Disposition, we well as write out the contents of the MIME part into the Stream that is provided. The MIME helper class will do the job of formatting the MIME part and uploading it to a HTTP endpoint.&lt;br /&gt;
&lt;br /&gt;
With this, we can now write out a derived class that can upload textual input data (i.e not file contents)&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;class NameValuePart : MimePart
    {
        private NameValueCollection nameValues;

        public NameValuePart(NameValueCollection nameValues)
        {
            this.nameValues = nameValues;
        }

        public override void CopyTo(Stream stream)
        {
            string boundary = this.Boundary;
            StringBuilder sb = new StringBuilder();

            foreach (object element in this.nameValues.Keys)
            {
                sb.AppendFormat("--{0}", boundary);
                sb.Append("\r\n");
                sb.AppendFormat("Content-Disposition: form-data; name=\"{0}\";", element);
                sb.Append("\r\n");
                sb.Append("\r\n");
                sb.Append(this.nameValues[element.ToString()]);

                sb.Append("\r\n");

            }

            sb.AppendFormat("--{0}", boundary);
            sb.Append("\r\n");

            //Trace.WriteLine(sb.ToString());
            byte [] data = Encoding.ASCII.GetBytes(sb.ToString());
            stream.Write(data, 0, data.Length);
        }

        public override string ContentDisposition
        {
            get { return "form-data"; }
        }

        public override string ContentType
        {
            get { return String.Empty; }
        }
    }&amp;nbsp;&lt;/pre&gt;&lt;pre class="c#" name="code"&gt;&amp;nbsp;&lt;/pre&gt;&lt;br /&gt;
&lt;div&gt;&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;NameValuePart &lt;/b&gt;is an implementation of the MimePart abstract class. It does the job of serializing the Name/Value pairs as a MIME encapsulated part.&lt;br /&gt;
&lt;br /&gt;
Next, we write the implementation of the class the encapsulates file uploads as a MIME part.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;class FilePart : MimePart

{

private Stream input;

private String contentType;



public FilePart(Stream input, String name, String contentType)

{

this.input = input;

this.contentType = contentType;

this.Name = name;

}



public override void CopyTo(Stream stream)

{

StringBuilder sb = new StringBuilder();

sb.AppendFormat("Content-Disposition: {0}", this.ContentDisposition);

if (this.Name != null)

sb.Append("; ").AppendFormat("name=\"{0}\"", this.Name);

if (this.FileName != null)

sb.Append("; ").AppendFormat("filename=\"{0}\"", this.FileName);

sb.Append("\r\n");

sb.AppendFormat(this.ContentType);

sb.Append("\r\n");

sb.Append("\r\n");



// serialize the header data.

byte[] buffer = Encoding.ASCII.GetBytes(sb.ToString());

stream.Write(buffer, 0, buffer.Length);



// send the stream.

byte[] readBuffer = new byte[1024];

int read = input.Read(readBuffer, 0, readBuffer.Length);

while (read &amp;gt; 0)

{

stream.Write(readBuffer, 0, read);

read = input.Read(readBuffer, 0, readBuffer.Length);

}



// write the terminating boundary

sb.Length = 0;

sb.Append("\r\n");

sb.AppendFormat("--{0}", this.Boundary);

sb.Append("\r\n");

buffer = Encoding.ASCII.GetBytes(sb.ToString());

stream.Write(buffer, 0, buffer.Length);



}



public override string ContentDisposition

{

get { return "file"; }

}



public override string ContentType

{

get { return String.Format("content-type: {0}", this.contentType); }

}



public String FileName { get; set; }

}

&lt;/pre&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;
According to the HTML Form upload specification, when the form defines more than one FILE INPUT field, then all the files in the form can be uploaded as one MIME type (of type multipart/mixed) that encapsulates each file, and each file will have it's own MIME encapsulation. In order to support this, we need to create a special class that can encapsulate FILE types.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;/// &lt;summary&gt;
        /// Helper class that encapsulates all file uploads
        /// in a mime part.
        /// &lt;/summary&gt;
        class FilesCollection : MimePart
        {
            private List&lt;filepart&gt; files;

            public FilesCollection()
            {
                this.files = new List&lt;filepart&gt;();
                this.Boundary = MultipartHelper.GetBoundary();
            }

            public int Count
            {
                get { return this.files.Count; }
            }

            public override string ContentDisposition
            {
                get
                {
                    return String.Format("form-data; name=\"{0}\"", this.Name);
                }
            }

            public override string ContentType
            {
                get { return String.Format("multipart/mixed; boundary={0}", this.Boundary); }
            }

            public override void CopyTo(Stream stream)
            {
                // serialize the headers
                StringBuilder sb = new StringBuilder(128);
                sb.Append("Content-Disposition: ").Append(this.ContentDisposition).Append("\r\n");
                sb.Append("Content-Type: ").Append(this.ContentType).Append("\r\n");
                sb.Append("\r\n");
                sb.AppendFormat("--{0}", this.Boundary).Append("\r\n");

                byte[] headerBytes = Encoding.ASCII.GetBytes(sb.ToString());
                stream.Write(headerBytes, 0, headerBytes.Length);
                foreach (FilePart part in files)
                {
                    part.Boundary = this.Boundary;
                    part.CopyTo(stream);
                }
            }

            public void Add(FilePart part)
            {
                this.files.Add(part);
            }
        }

&lt;/filepart&gt;&lt;/filepart&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;div&gt;&lt;/div&gt;&lt;br /&gt;
This class does the job of encapsulating FILE parts inside a MIME container.&lt;br /&gt;
&lt;br /&gt;
Now, we just need to write the code that can put this all together.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;/// &lt;summary&gt;
    /// Helper class to aid in uploading multipart
    /// entities to HTTP web endpoints.
    /// &lt;/summary&gt;
    class MultipartHelper
    {
        private static Random random = new Random(Environment.TickCount);

        private List&lt;namevaluepart&gt; formData = new List&lt;namevaluepart&gt;();
        private FilesCollection files = null;
        private MemoryStream bufferStream = new MemoryStream();
        private string boundary;

        public String Boundary { get { return boundary; } }

        public static String GetBoundary()
        {
            return Environment.TickCount.ToString("X");
        }

        public MultipartHelper()
        {
            this.boundary = MultipartHelper.GetBoundary();
        }

        public void Add(NameValuePart part)
        {
            this.formData.Add(part);
            part.Boundary = boundary;
        }

        public void Add(FilePart part)
        {
            if (files == null)
            {
                files = new FilesCollection();
            }
            this.files.Add(part);
        }

        public void Upload(WebClient client, string address, string method)
        {
            // set header
            client.Headers.Add(HttpRequestHeader.ContentType, "multipart/form-data; boundary=" + this.boundary);
            Trace.WriteLine("Content-Type: multipart/form-data; boundary=" + this.boundary + "\r\n");

            // first, serialize the form data
            foreach (NameValuePart part in this.formData)
            {
                part.CopyTo(bufferStream);
            }

            // serialize the files.
            this.files.CopyTo(bufferStream);

            if (this.files.Count &amp;gt; 0)
            {
                // add the terminating boundary.
                StringBuilder sb = new StringBuilder();
                sb.AppendFormat("--{0}", this.Boundary).Append("\r\n");
                byte [] buffer = Encoding.ASCII.GetBytes(sb.ToString());
                bufferStream.Write(buffer, 0, buffer.Length);
            }

            bufferStream.Seek(0, SeekOrigin.Begin);

            Trace.WriteLine(Encoding.ASCII.GetString(bufferStream.ToArray()));
            byte [] response = client.UploadData(address, method, bufferStream.ToArray());
            Trace.WriteLine("----- RESPONSE ------");
            Trace.WriteLine(Encoding.ASCII.GetString(response));
        }

        /// &lt;summary&gt;
        /// Helper class that encapsulates all file uploads
        /// in a mime part.
        /// &lt;/summary&gt;
        class FilesCollection : MimePart
        {
            private List&lt;filepart&gt; files;

            public FilesCollection()
            {
                this.files = new List&lt;filepart&gt;();
                this.Boundary = MultipartHelper.GetBoundary();
            }

            public int Count
            {
                get { return this.files.Count; }
            }

            public override string ContentDisposition
            {
                get
                {
                    return String.Format("form-data; name=\"{0}\"", this.Name);
                }
            }

            public override string ContentType
            {
                get { return String.Format("multipart/mixed; boundary={0}", this.Boundary); }
            }

            public override void CopyTo(Stream stream)
            {
                // serialize the headers
                StringBuilder sb = new StringBuilder(128);
                sb.Append("Content-Disposition: ").Append(this.ContentDisposition).Append("\r\n");
                sb.Append("Content-Type: ").Append(this.ContentType).Append("\r\n");
                sb.Append("\r\n");
                sb.AppendFormat("--{0}", this.Boundary).Append("\r\n");

                byte[] headerBytes = Encoding.ASCII.GetBytes(sb.ToString());
                stream.Write(headerBytes, 0, headerBytes.Length);
                foreach (FilePart part in files)
                {
                    part.Boundary = this.Boundary;
                    part.CopyTo(stream);
                }
            }

            public void Add(FilePart part)
            {
                this.files.Add(part);
            }
        }
    }

&lt;/filepart&gt;&lt;/filepart&gt;&lt;/namevaluepart&gt;&lt;/namevaluepart&gt;&lt;/pre&gt;&lt;br /&gt;
Since the job of serializing to MIME has been delegated to each concrete implementation of MimePart class, the MultipartHelper only has to make sure that it uses the different parts and serializes them into a stream. The stream is then uploaded using the supplied WebClient.&lt;br /&gt;
&lt;br /&gt;
Note that I have put the FilesCollection class as an inner class of the MultipartHelper class, because it is meant to be a helper class that should not be directly accessed by the clients.&lt;br /&gt;
&lt;br /&gt;
The client program for this looks as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="c#" name="code"&gt;class Program
    {
        static void Main(string[] args)
        {
            Trace.Listeners.Add(new ConsoleTraceListener());
            try
            {
                using (StreamWriter sw = new StreamWriter("testfile.txt", false))
                {
                    sw.Write("Hello there!");
                }

                using (Stream iniStream = File.OpenRead(@"c:\platform.ini"))
                using (Stream fileStream = File.OpenRead("testfile.txt"))
                using (WebClient client = new WebClient())
                {
                    MultipartHelper helper = new MultipartHelper();

                    NameValueCollection props = new NameValueCollection();
                    props.Add("fname", "john");
                    props.Add("id", "acme");
                    helper.Add(new NameValuePart(props));

                    FilePart filepart = new FilePart(fileStream, "pics1", "text/plain");
                    filepart.FileName = "1.jpg";
                    helper.Add(filepart);

                    FilePart ini = new FilePart(iniStream, "pics2", "text/plain");
                    ini.FileName = "inifile.ini";
                    helper.Add(ini);

                    helper.Upload(client, "http://localhost/form.aspx", "POST");
                }
            }
            catch (Exception e)
            {
                Trace.WriteLine(e);
            }
        }
    }

&lt;/pre&gt;&lt;br /&gt;
&lt;div&gt;&lt;/div&gt;&lt;br /&gt;
If you want to understand what is going on at the wire level, you can &lt;a href="http://ferozedaud.blogspot.com/2009/08/tracing-with-systemnet.html"&gt;create a system.net trace log&lt;/a&gt; which will show the details.&lt;br /&gt;
&lt;br /&gt;
&lt;iframe align="left" class=" erjuwbkpsnbxegktyryu erjuwbkpsnbxegktyryu erjuwbkpsnbxegktyryu" frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm.amazon.com/e/cm?t=ferozesmusings-20&amp;amp;o=1&amp;amp;p=8&amp;amp;l=bpl&amp;amp;asins=1430225297&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;m=amazon&amp;amp;lc1=0000FF&amp;amp;bc1=000000&amp;amp;bg1=FFFFFF&amp;amp;f=ifr" style="height: 245px; padding-right: 10px; padding-top: 5px; width: 131px;"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6013019333081665053-1885982241824977710?l=ferozedaud.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/XWs9wTlba73hyZOJV3DorjiMzFE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/XWs9wTlba73hyZOJV3DorjiMzFE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/XWs9wTlba73hyZOJV3DorjiMzFE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/XWs9wTlba73hyZOJV3DorjiMzFE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FerozesMusingsOnTechnology/~4/qZweysIWYPA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ferozedaud.blogspot.com/feeds/1885982241824977710/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://ferozedaud.blogspot.com/2010/03/multipart-form-upload-helper.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/1885982241824977710?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/1885982241824977710?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/FerozesMusingsOnTechnology/~3/qZweysIWYPA/multipart-form-upload-helper.html" title="Multipart Form Upload Helper" /><author><name>Feroze Daud</name><uri>https://profiles.google.com/106931323736171420480</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-htqG4D1zj34/AAAAAAAAAAI/AAAAAAAAAJM/o1zOCSZPA3c/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://ferozedaud.blogspot.com/2010/03/multipart-form-upload-helper.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0IFR3g5fSp7ImA9Wx5UGU0.&quot;"><id>tag:blogger.com,1999:blog-6013019333081665053.post-745642508742798939</id><published>2009-12-06T14:05:00.000-08:00</published><updated>2010-10-23T23:25:16.625-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-23T23:25:16.625-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Socket" /><category scheme="http://www.blogger.com/atom/ns#" term="TransmitFile" /><category scheme="http://www.blogger.com/atom/ns#" term="System.Net" /><category scheme="http://www.blogger.com/atom/ns#" term="SendFile" /><title>Socket.SendFile - Implementing fast file transfer</title><content type="html">&lt;h1&gt;Implementing fast file transfer with Socket.SendFile &lt;/h1&gt;When writing network applications, we usually have a need to implement file transfer between two hosts. For eg, imaging an FTP client, where the client is downloading or uploading a file from an FTP server. Similarly, you could be uploading an image file (probably a photo) as an attachment to a Blog or a website like Facebook or Flickr.&lt;br /&gt;
&lt;br /&gt;
Usually, file transfer is implemented as a Read/Write pattern, where you read from the source stream and write into the destination stream. Here the source stream is the stream constructed from the Socket, and the target stream is the file, or vice versa if the file is being transferred to a destination server.&lt;br /&gt;
&lt;br /&gt;
The simple Read/Write pattern for file transfer is implemented as follows.&lt;br /&gt;
&lt;br /&gt;
&lt;pre name="code" class="c#"&gt;using (FileStream fs = File.OpenRead(filename))
                {
                    byte[] buffer = new byte[1024];
                    int read = fs.Read(buffer, 0, buffer.Length);

                    while (read &amp;gt; 0)
                    {
                        ns.Write(buffer, 0, read);
                        read = fs.Read(buffer, 0, buffer.Length);
                    }
                }
&lt;/pre&gt;&lt;br /&gt;
In the .NET framework, there is a better way to do file uploads, which is exposed through &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.sendfile.aspx"&gt;Socket.SendFile&lt;/a&gt; method. This method exposes the underlying Winsock API &lt;a href="http://msdn.microsoft.com/en-us/library/ms740565%28VS.85%29.aspx"&gt;TransmitFile&lt;/a&gt;. This API is much more powerful and faster in terms of performance.&lt;br /&gt;
&lt;br /&gt;
In order to check the performance difference, I wrote an application that compares the difference in performance between using the Read/Write pattern and the Socket.SendFile method.&lt;br /&gt;
&lt;br /&gt;
Here is the test program:&lt;br /&gt;
&lt;br /&gt;
&lt;pre name="code" class="c#"&gt;using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Net.Cache;
using System.Threading;

namespace socket_sendfile
{
    delegate TimeSpan SendFileDelegate(Socket client, String filename, long fileSize);

    class Header
    {
        public long FileSize { get; set; }
        public int FileNumber { get; set; }

        public void Serialize(Stream stream)
        {
            byte[] buffer = BitConverter.GetBytes(this.FileNumber);
            stream.Write(buffer, 0, buffer.Length);

            buffer = BitConverter.GetBytes(this.FileSize);
            stream.Write(buffer, 0, buffer.Length);
        }

        public static Header Deserialize(Stream stream)
        {
            Header header = new Header();

            byte[] buffer = new byte[4];
            int read = stream.Read(buffer, 0, buffer.Length);
            header.FileNumber = BitConverter.ToInt32(buffer, 0);

            buffer = new byte[sizeof(long)];
            read = stream.Read(buffer, 0, buffer.Length);
            header.FileSize = BitConverter.ToInt64(buffer, 0);
            return header;
        }
    }

    class Program
    {
        private Random rand = new Random();

        static void Main(string[] args)
        {
            Program prog = new Program();

            try
            {
                prog.StartServer();

                using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
                {
                    client.Bind(new IPEndPoint(0, 0));
                    client.Connect(new IPEndPoint(IPAddress.Loopback, 8080));

                    prog.Run(client, new SendFileDelegate(prog.SendFile1));

                    Console.WriteLine();
                    prog.Run(client, new SendFileDelegate(prog.SendFile2));
                }
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e);
            }
        }

        void StartServer()
        {
            Thread serverThread = new Thread(new ThreadStart(this.Server));
            serverThread.Start();
        }

        void Run(Socket client, SendFileDelegate sendFileMethod)
        {
            foreach (long size in this.GetNextSize())
            {
                String filename = Path.GetTempFileName();

                this.CreateFile(filename, size);

                for (int i = 0; i &amp;lt; 10; i++)
                {
                    TimeSpan ts = sendFileMethod(client, filename, size);
                    Console.WriteLine("{0} {1} {2}", i, size, ts.TotalMilliseconds);
                }
            }
        }

        IEnumerable&lt;ulong&gt; GetNextSize()
        {
            ulong[] sizes = { 1024, 4096, 8192, 16385, 65536, 1048576 };
            for (int i = 0; i &amp;lt; sizes.Length; i++)
            {
                yield return sizes[i];
            }
        }

        void CreateFile(string filename, long size)
        {
            byte[] buffer = new byte[16384];

            // first write out the file.
            using (FileStream tempStream = File.OpenWrite(filename))
            using (BinaryWriter bw = new BinaryWriter(tempStream))
            {
                long remaining = size;
                while (remaining &amp;gt; 0)
                {
                    rand.NextBytes(buffer);
                    int writeSize = buffer.Length;
                    if (writeSize &amp;gt; (int)remaining)
                    {
                        writeSize = (int)remaining;
                    }

                    bw.Write(buffer, 0, writeSize);
                    remaining -= writeSize;
                }
            }
        }

        TimeSpan SendFile1(Socket client, String filename, long fileSize)
        {
            Stopwatch timer = new Stopwatch();

            timer.Start();
            using (NetworkStream ns = new NetworkStream(client))
            {
                Header header = new Header();
                header.FileSize = fileSize;
                header.FileNumber = 1;

                // send the header
                header.Serialize(ns);

                using (FileStream fs = File.OpenRead(filename))
                {
                    byte[] buffer = new byte[1024];
                    int read = fs.Read(buffer, 0, buffer.Length);

                    while (read &amp;gt; 0)
                    {
                        ns.Write(buffer, 0, read);
                        read = fs.Read(buffer, 0, buffer.Length);
                    }
                }
            }

            timer.Stop();

            return timer.Elapsed;
        }

        TimeSpan SendFile2(Socket client, String filename, long fileSize)
        {
            Stopwatch timer = new Stopwatch();

            timer.Start();
            using (NetworkStream ns = new NetworkStream(client))
            {
                Header header = new Header();
                header.FileSize = fileSize;
                header.FileNumber = 1;

                byte[] headerBuffer = null;
                using(MemoryStream ms = new MemoryStream())
                {
                    header.Serialize(ms);
                    ms.Seek(0, SeekOrigin.Begin);
                    headerBuffer = ms.ToArray();
                }

                // send the header
                client.SendFile(filename, headerBuffer, null, TransmitFileOptions.UseDefaultWorkerThread);
                
            }

            timer.Stop();

            return timer.Elapsed;
        }

        void Server()
        {
            byte [] buffer = new byte[1024];
            TcpListener listener = new TcpListener(8080);
            listener.Start();
            using (TcpClient client = listener.AcceptTcpClient())
            using (NetworkStream ns = client.GetStream())
            {
                bool hasData = true;
                while (hasData)
                {
                    // first get the header. Header has the file size.
                    Header header = Header.Deserialize(ns);

                    long remaining = header.FileSize;

                    while (remaining &amp;gt; 0)
                    {
                        int readSize = buffer.Length;
                        if ((long)readSize &amp;gt; remaining)
                            readSize = (int)remaining;

                        int read = ns.Read(buffer, 0, readSize);
                        remaining -= read;
                    }
                }
            }
        }
    }
}
&lt;/ulong&gt;&lt;/pre&gt;&lt;br /&gt;
A couple of things to note about this implementation:&lt;br /&gt;
&lt;br /&gt;
1) It uses Message framing to frame file transfers, since it uses the same socket for multiple file transfers. I have used the techniques in &lt;a href="http://ferozedaud.blogspot.com/2009/11/howto-serialize-data-from-object-from.html"&gt;Serializing data from .NET to Java&lt;/a&gt; to do this. Even though there is no Java app that is involved here, the techniques are the same.&lt;br /&gt;
&lt;br /&gt;
2) The server just drains the incoming stream. It does not save the incoming data to a file. Since we are just interested in benchmarking the performance between the two Send implementations, we should be ok here.&lt;br /&gt;
&lt;br /&gt;
3) The program, which is basically a perf harness, uses a Strategy pattern to change the SendFile method used. That way everything else remains the same, and it just changes the SendFile method to get performance numbers.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Perf Comparison&lt;br /&gt;
&lt;br /&gt;
The following graph shows the performance with the simple Read/Write pattern for file transfer.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BUWqOvN26Oc/SxwpipTrlrI/AAAAAAAAAGM/fcKLBEYFC40/s1600-h/without-sendfile.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_BUWqOvN26Oc/SxwpipTrlrI/AAAAAAAAAGM/fcKLBEYFC40/s320/without-sendfile.png" ALT="performance of file transfer with Socket.BeginSend" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
The following chart shows the performance when Socket.SendFile is used.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_BUWqOvN26Oc/Sxwp0P6N1tI/AAAAAAAAAGc/2AOz8UEKafs/s1600-h/with-sendfile.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_BUWqOvN26Oc/Sxwp0P6N1tI/AAAAAAAAAGc/2AOz8UEKafs/s320/with-sendfile.png" alt="performance of file transfer with Socket.SendFile" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
As you can see, there is a huge difference between the two, specially for 1M file size. With Socket.SendFile, it takes max 129ms for upload, whereas without this API, it takes 1000ms for upload. For smaller file sizes, there is not that much of a difference.&lt;br /&gt;
&lt;br /&gt;
There is a huge variance in timings for the SendFile() method for 1M file size, but I havent been able to figure out the reason for that yet. Anyway, the fact that Socket.SendFile() is faster should not&amp;nbsp; be impacted by that.&lt;br /&gt;
&lt;br /&gt;
&lt;iframe src="http://rcm.amazon.com/e/cm?t=ferozesmusings-20&amp;o=1&amp;p=8&amp;l=bpl&amp;asins=0138487146&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr" style="align:left;padding-top:5px;width:131px;height:245px;padding-right:10px;"align="left" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;iframe src="http://rcm.amazon.com/e/cm?t=ferozesmusings-20&amp;o=1&amp;p=8&amp;l=bpl&amp;asins=073561959X&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr" style="align:left;padding-top:5px;width:131px;height:245px;padding-right:10px;"align="left" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6013019333081665053-745642508742798939?l=ferozedaud.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/-5OBtbLhXJZAifoRVQBB-W-ZHTA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-5OBtbLhXJZAifoRVQBB-W-ZHTA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/-5OBtbLhXJZAifoRVQBB-W-ZHTA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-5OBtbLhXJZAifoRVQBB-W-ZHTA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FerozesMusingsOnTechnology/~4/T5IXUybQYg0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ferozedaud.blogspot.com/feeds/745642508742798939/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://ferozedaud.blogspot.com/2009/12/socketsendfile-implementing-fast-file.html#comment-form" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/745642508742798939?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/745642508742798939?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/FerozesMusingsOnTechnology/~3/T5IXUybQYg0/socketsendfile-implementing-fast-file.html" title="Socket.SendFile - Implementing fast file transfer" /><author><name>Feroze Daud</name><uri>https://profiles.google.com/106931323736171420480</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-htqG4D1zj34/AAAAAAAAAAI/AAAAAAAAAJM/o1zOCSZPA3c/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_BUWqOvN26Oc/SxwpipTrlrI/AAAAAAAAAGM/fcKLBEYFC40/s72-c/without-sendfile.png" height="72" width="72" /><thr:total>5</thr:total><feedburner:origLink>http://ferozedaud.blogspot.com/2009/12/socketsendfile-implementing-fast-file.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUQFQHo5cCp7ImA9WxBTF08.&quot;"><id>tag:blogger.com,1999:blog-6013019333081665053.post-4731345406734264262</id><published>2009-11-15T15:45:00.000-08:00</published><updated>2009-12-13T10:01:51.428-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-13T10:01:51.428-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Socket" /><category scheme="http://www.blogger.com/atom/ns#" term="Network" /><category scheme="http://www.blogger.com/atom/ns#" term="BinaryReader" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="System.Net" /><category scheme="http://www.blogger.com/atom/ns#" term="DataOutputStream" /><category scheme="http://www.blogger.com/atom/ns#" term="DataInputStream" /><category scheme="http://www.blogger.com/atom/ns#" term="BinaryWriter" /><category scheme="http://www.blogger.com/atom/ns#" term="ByteBuffer" /><title>How to send object from Java to .NET: Alternate implementation</title><content type="html">In the last article, I described how to send an object from a Java application to a .NET application over a Socket connection.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://ferozedaud.blogspot.com/2009/11/howto-serialize-data-from-object-from.html"&gt;http://ferozedaud.blogspot.com/2009/11/howto-serialize-data-from-object-from.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
The Java implementation was relying on ByteBuffer class to serialize the object in LittleEndian format that the .NET code understands.&lt;br /&gt;
&lt;br /&gt;
However, it turns out that using a ByteBuffer is not necessary. Java's native format is BigEndian. The network byte order is also BigEndian. However, the X86 platform (and .NET) are LittleEndian. So, we only need a way to convert from BigEndian to LittleEndian and vice versa on .NET.&lt;br /&gt;
&lt;br /&gt;
In .NET, the &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.ipaddress.hosttonetworkorder(VS.71).aspx"&gt;IPAddress.HostToNetworkOrder&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.ipaddress.networktohostorder(VS.71).aspx"&gt;IPAddress.NetworkToHostOrder&lt;/a&gt; methods are provided for doing this conversion.&lt;br /&gt;
&lt;br /&gt;
On the java application, we can forego the ByteBuffer and use DataInputStream/DataOutputStream directly. This makes the code more concise and easy to understand.&lt;br /&gt;
&lt;br /&gt;
With these changes, the .NET application looks as follows: (I am only including changes to the Read() method, the other stuff is the same.&lt;br /&gt;
&lt;br /&gt;
&lt;pre name="code" class="csharp"&gt;static void Read(TcpClient client)
        {
            Console.WriteLine("Got connection: {0}", DateTime.Now);
            NetworkStream ns = client.GetStream();
            BinaryReader reader = new BinaryReader(ns);

            Employee emp = new Employee();
            // first read the Id
            emp.Id = IPAddress.NetworkToHostOrder(reader.ReadInt32());

            // length of first name in bytes.
            int length = IPAddress.NetworkToHostOrder(reader.ReadInt32());
            
            // read the name bytes into the byte array.
            // recall that java side is writing two bytes for every character.
            byte[] nameArray = reader.ReadBytes(length);
            emp.FirstName = Encoding.UTF8.GetString(nameArray);

            // last name
            length = IPAddress.NetworkToHostOrder(reader.ReadInt32());
            nameArray = reader.ReadBytes(length);
            emp.LastName = Encoding.UTF8.GetString(nameArray);

            // salary
            emp.Salary = IPAddress.NetworkToHostOrder(reader.ReadInt32());

            Console.WriteLine(emp.Id);
            Console.WriteLine(emp.FirstName);
            Console.WriteLine(emp.LastName);
            Console.WriteLine(emp.Salary);

            System.Threading.Thread.Sleep(5);

            Console.WriteLine("Writing data...");
            // now reflect back the same structure.
            BinaryWriter bw = new BinaryWriter(ns);

            bw.Write(IPAddress.HostToNetworkOrder(emp.Id));
            byte [] data = Encoding.UTF8.GetBytes(emp.FirstName);
            bw.Write(IPAddress.HostToNetworkOrder(data.Length));
            bw.Write(data);
            
            data = Encoding.UTF8.GetBytes(emp.LastName);
            bw.Write(IPAddress.HostToNetworkOrder(data.Length));
            bw.Write(data);

            bw.Write(IPAddress.HostToNetworkOrder(emp.Salary));

            Console.WriteLine("Writing data...DONE");

            client.Client.Shutdown(SocketShutdown.Both);
            ns.Close();
        }
&lt;/pre&gt;&lt;br /&gt;
As you can see, we still use BinaryReader/BinaryWriter. However we just call NetworkToHostOrder or HostToNetworkOrder before writing the bytes on the wire.&lt;br /&gt;
&lt;br /&gt;
On the java application, there are changes in the Main() method and the serialize() method. We directly work with DataInputStream/DataOutputStream which are similar to .NET's BinaryReader/BinaryWriter.&lt;br /&gt;
&lt;br /&gt;
&lt;pre name="code" class="java"&gt;public static void main(String [] args)
 { 
  int written = 0;
  EmployeeData emp = new EmployeeData();
  emp.setFirstName("John");
  emp.setLastName("Smith");
  emp.setId(1);
  emp.setSalary(2);
  
  // Create the encoder and decoder for targetEncoding
  Charset charset = Charset.forName("UTF-8");
  CharsetDecoder decoder = charset.newDecoder();
  CharsetEncoder encoder = charset.newEncoder();

  try
  {
   Socket client = new Socket("localhost", 8080);
   
   OutputStream oStream = client.getOutputStream();
   InputStream iStream = client.getInputStream();

   DataOutputStream dos = new DataOutputStream(oStream);

   serializeToStream(dos, emp, encoder);

   DataInputStream dis = new DataInputStream(iStream);

   // now client echoes back the data.
   EmployeeData rEmp = new EmployeeData();
   rEmp.setId(dis.readInt());
   
   int length = dis.readInt();
   System.out.println("FName Length: " + length);
   byte [] stringBuffer = new byte[length];
   dis.read(stringBuffer);
   rEmp.setFirstName(decoder.decode(ByteBuffer.wrap(stringBuffer)).toString());
   
   length = dis.readInt();
   System.out.println("LName Length: " + length);
   stringBuffer = new byte[length];
   dis.read(stringBuffer);
   rEmp.setLastName(decoder.decode(ByteBuffer.wrap(stringBuffer)).toString());
   
   rEmp.setSalary(dis.readInt());
   
   System.out.println("ID: " + rEmp.getId());
   System.out.println("First: " + rEmp.getFirstName());
   System.out.println("Last: " + rEmp.getLastName());
   System.out.println("Salary: " + rEmp.getSalary());
   System.out.flush();
   
   client.close();
   
  } catch(Exception e) {
   e.printStackTrace(System.err);
  } finally {
   System.out.println("Written bytes: " + written);
  }
 }
 
 private static void serializeToStream(DataOutputStream os, EmployeeData emp, CharsetEncoder encoder) throws IOException
 {
  // id
  os.writeInt(emp.getId());
  
  CharBuffer nameBuffer = CharBuffer.wrap(emp.getFirstName().toCharArray());
  ByteBuffer nbBuffer = null;
  
  // length of first name
  try
  {
   nbBuffer = encoder.encode(nameBuffer);
  } 
  catch(CharacterCodingException e)
  {
   throw new ArithmeticException();
  }

  System.out.println(String.format("String [%1$s] #bytes = %2$s", emp.getFirstName(), nbBuffer.limit()));
  os.writeInt(nbBuffer.limit());
  os.write(nbBuffer.array());

  // put lastname
  nameBuffer = CharBuffer.wrap(emp.getLastName().toCharArray());
  nbBuffer = null;
  
  // length of first name
  try
  {
   nbBuffer = encoder.encode(nameBuffer);   
  } 
  catch(CharacterCodingException e)
  {
   throw new ArithmeticException();
  }

  System.out.println(String.format("String [%1$s] #bytes = %2$s", emp.getLastName(), nbBuffer.limit()));
  os.writeInt(nbBuffer.limit());
  os.write(nbBuffer.array());
  
  // salary
  os.writeInt(emp.getSalary());
 }
&lt;/pre&gt;&lt;br /&gt;
We do not need to use ByteBuffer anymore - we were only using it because it supports LittleEndian format. The java app always expects to read/write bytes from the wire in BigEndian format (which is java's native format, as well as the Network order for all communications). The .NET application does the conversion from BigEndian to LittleEndian and back.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6013019333081665053-4731345406734264262?l=ferozedaud.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/EqiNDh1wTJ4R8WrMA4pjWaRxwUU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/EqiNDh1wTJ4R8WrMA4pjWaRxwUU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/EqiNDh1wTJ4R8WrMA4pjWaRxwUU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/EqiNDh1wTJ4R8WrMA4pjWaRxwUU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FerozesMusingsOnTechnology/~4/n8zODGKlA_Y" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ferozedaud.blogspot.com/feeds/4731345406734264262/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://ferozedaud.blogspot.com/2009/11/how-to-send-object-from-java-to-net.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/4731345406734264262?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/4731345406734264262?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/FerozesMusingsOnTechnology/~3/n8zODGKlA_Y/how-to-send-object-from-java-to-net.html" title="How to send object from Java to .NET: Alternate implementation" /><author><name>Feroze Daud</name><uri>https://profiles.google.com/106931323736171420480</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-htqG4D1zj34/AAAAAAAAAAI/AAAAAAAAAJM/o1zOCSZPA3c/s512-c/photo.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://ferozedaud.blogspot.com/2009/11/how-to-send-object-from-java-to-net.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkcDR3g8cCp7ImA9WxNbEko.&quot;"><id>tag:blogger.com,1999:blog-6013019333081665053.post-8214252598153156082</id><published>2009-11-15T00:34:00.000-08:00</published><updated>2009-11-15T00:34:36.678-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-15T00:34:36.678-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Socket" /><category scheme="http://www.blogger.com/atom/ns#" term="Network" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="System.Net" /><category scheme="http://www.blogger.com/atom/ns#" term="Logging" /><category scheme="http://www.blogger.com/atom/ns#" term="ByteBuffer" /><title>HOWTO: Serialize data from an object from .NET to Java using custom binary formatting.</title><content type="html">Problem: You want to send data across the network, from a .NET application to a Java application (or vice versa). The data is actually an object that you want to send over the network.&lt;br /&gt;
&lt;br /&gt;
Since these are heterogenous platforms, you cannot use the Runtime specific serialization methods (for eg BinaryFormatter in .NET). You need to roll your own.&lt;br /&gt;
&lt;br /&gt;
You basically have two choices. You can manually transfer the data, by converting the primitive types from one platform into a binary, over the wire representation. On the other side, you need to convert the binary, over the wire representation into a primitive type of the platform.&lt;br /&gt;
&lt;br /&gt;
The other option is to use a serialization method supported by the platform, for eg XmlSerialization. You would then write code on the peer to parse the XML document from the network and convert it into your object representation. Since XML is a portable standard, you can do this fairly easily.&lt;br /&gt;
&lt;br /&gt;
In this article, I will be talking about the first, i.e how to do Binary Serialization manually.&lt;br /&gt;
&lt;br /&gt;
In order to demonstrate this, we will work with the following object in Java.&lt;br /&gt;
&lt;br /&gt;
&lt;pre name="code" class="java"&gt;package net.example;

public class EmployeeData {
 private int id;
 private String firstName;
 private String lastName;
 private int salary;
 
 public void setId(int id) {
  this.id = id;
 }
 public int getId() {
  return id;
 }
 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }
 public String getFirstName() {
  return firstName;
 }
 public void setLastName(String lastName) {
  this.lastName = lastName;
 }
 public String getLastName() {
  return lastName;
 }
 public void setSalary(int salary) {
  this.salary = salary;
 }
 public int getSalary() {
  return salary;
 }
}
&lt;/pre&gt;&lt;br /&gt;
This has an equivalent object in .NET&lt;br /&gt;
&lt;br /&gt;
&lt;pre name="code" class="csharp"&gt;class Employee
    {
        public int Id;
        public String FirstName;
        public String LastName;
        public int Salary;
    }
&lt;/pre&gt;&lt;br /&gt;
As you can see, these objects are fairly equivalent in terms of schema.&lt;br /&gt;
&lt;br /&gt;
For each of the platforms, the program will be similar. Each application will receive data that purports to be an Employee record. The app will deserialize the data into an employee record. It will then send the same data back to the peer. The peer will then deserialize the data back into it's equivalent Employee structure. Thus, this will demonstrate a good round-trip between the heterogenous platforms.&lt;br /&gt;
&lt;br /&gt;
First, let us look at the complete application in .NET.&lt;br /&gt;
&lt;br /&gt;
&lt;pre name="code" class="csharp"&gt;using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;

namespace netSock
{
    class Employee
    {
        public int Id;
        public String FirstName;
        public String LastName;
        public int Salary;
    }

    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Run(args);
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e);
            }
        }

        static void Run(string[] args)
        {
            TcpListener listener = new TcpListener(8080);
            listener.Start();

            while (true)
            {

                using (TcpClient client = listener.AcceptTcpClient())
                {
                    try
                    {
                        Read(client);
                    }
                    catch (Exception e)
                    {
                        Console.Error.WriteLine(e);
                    }
                }
            }
        }

        static void Read(TcpClient client)
        {
            Console.WriteLine("Got connection: {0}", DateTime.Now);
            NetworkStream ns = client.GetStream();
            BinaryReader reader = new BinaryReader(ns);

            Employee emp = new Employee();
            // first read the Id
            emp.Id = reader.ReadInt32();

            // length of first name in bytes.
            int length = reader.ReadInt32();
            
            // read the name bytes into the byte array.
            // recall that java side is writing two bytes for every character.
            byte[] nameArray = reader.ReadBytes(length);
            emp.FirstName = Encoding.UTF8.GetString(nameArray);

            // last name
            length = reader.ReadInt32();
            nameArray = reader.ReadBytes(length);
            emp.LastName = Encoding.UTF8.GetString(nameArray);

            // salary
            emp.Salary = reader.ReadInt32();

            Console.WriteLine(emp.Id);
            Console.WriteLine(emp.FirstName);
            Console.WriteLine(emp.LastName);
            Console.WriteLine(emp.Salary);

            System.Threading.Thread.Sleep(5);

            Console.WriteLine("Writing data...");
            // now reflect back the same structure.
            BinaryWriter bw = new BinaryWriter(ns);

            bw.Write(emp.Id);
            byte [] data = Encoding.UTF8.GetBytes(emp.FirstName);
            bw.Write(data.Length);
            bw.Write(data);
            
            data = Encoding.UTF8.GetBytes(emp.LastName);
            bw.Write(data.Length);
            bw.Write(data);

            bw.Write(emp.Salary);

            Console.WriteLine("Writing data...DONE");

            client.Client.Shutdown(SocketShutdown.Both);
            ns.Close();
        }
    }
}
&lt;/pre&gt;&lt;br /&gt;
This program is very simple. It uses a TcpListener to create a server application, and waits for connections. After getting a connection, it reads data from the stream and deserializes it into a &lt;b&gt;Employee&lt;/b&gt; class. It then sends the object back to the sender by manually serializing the primitive types into the stream.&lt;br /&gt;
&lt;br /&gt;
The output of this program is as follows (when the java client connects to it):&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;Got connection: 11/15/2009 12:20:02 AM&lt;br /&gt;
1&lt;br /&gt;
John&lt;br /&gt;
Smith&lt;br /&gt;
2&lt;br /&gt;
Writing data...&lt;br /&gt;
Writing data...DONE&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
AS you can see, the employee First Name is "John" and Last name is "Smith".&lt;br /&gt;
&lt;br /&gt;
If you have some problem with this, then you can debug it by getting a &lt;a href="http://ferozedaud.blogspot.com/2009/08/tracing-with-systemnet.html"&gt;Tracelog&lt;/a&gt; for the application.&lt;br /&gt;
&lt;br /&gt;
Now, let us look at the java example application:&lt;br /&gt;
&lt;br /&gt;
&lt;pre name="code" class="java"&gt;package net.example;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;

public class Main {
 public static void main(String [] args)
 {
  
  int written = 0;
  EmployeeData emp = new EmployeeData();
  emp.setFirstName("John");
  emp.setLastName("Smith");
  emp.setId(1);
  emp.setSalary(2);
  
  // Create the encoder and decoder for targetEncoding
  Charset charset = Charset.forName("UTF-8");
  CharsetDecoder decoder = charset.newDecoder();
  CharsetEncoder encoder = charset.newEncoder();
  byte [] underlyingBuffer = new byte[1024];
  ByteBuffer buffer = ByteBuffer.wrap(underlyingBuffer);
  buffer.order(ByteOrder.LITTLE_ENDIAN);
  try
  {
   Socket client = new Socket("localhost", 8080);
   
   OutputStream oStream = client.getOutputStream();
   InputStream iStream = client.getInputStream();

   serialize(buffer, emp, encoder);
   
   buffer.flip();
   
   int dataToSend = buffer.remaining();
   System.out.println("# bytes = " + dataToSend);
   
   System.out.println("#Bytes in output buffer: " + written + " limit = " + buffer.limit() + " pos = " + buffer.position() + " remaining = " + buffer.remaining());
   
   int remaining = dataToSend;
   while(remaining &gt; 0)
   {
    oStream.write(buffer.get());
    -- remaining;
   }
   
   // now client echoes back the data.
   
   ByteBuffer readBuffer = ByteBuffer.allocate(1024);
   readBuffer.order(ByteOrder.LITTLE_ENDIAN);
   
   int db = iStream.read();
   while(db != -1)
   {
    System.out.println(db);
    readBuffer.put((byte)db);
    db = iStream.read();
   }
   
   int numberOfBytesRead = readBuffer.position();
   
   System.out.println("Number of bytes read: " + numberOfBytesRead);
   
   readBuffer.flip();

   EmployeeData rEmp = new EmployeeData();
   rEmp.setId(readBuffer.getInt());
   
   int length = readBuffer.getInt();
   System.out.println("FName Length: " + length);
   byte [] stringBuffer = new byte[length];
   readBuffer.get(stringBuffer);
   rEmp.setFirstName(decoder.decode(ByteBuffer.wrap(stringBuffer)).toString());
   
   length = readBuffer.getInt();
   System.out.println("LName Length: " + length);
   stringBuffer = new byte[length];
   readBuffer.get(stringBuffer);
   rEmp.setLastName(decoder.decode(ByteBuffer.wrap(stringBuffer)).toString());
   
   rEmp.setSalary(readBuffer.getInt());
   
   System.out.println("ID: " + rEmp.getId());
   System.out.println("First: " + rEmp.getFirstName());
   System.out.println("Last: " + rEmp.getLastName());
   System.out.println("Salary: " + rEmp.getSalary());
   System.out.flush();
   
   client.close();
   
  } catch(Exception e) {
   e.printStackTrace(System.err);
  } finally {
   System.out.println("Written bytes: " + written);
  }
 }
 
 private static void serialize(ByteBuffer buffer, EmployeeData emp, CharsetEncoder encoder)
 {
  // id
  buffer.putInt(emp.getId());
  
  CharBuffer nameBuffer = CharBuffer.wrap(emp.getFirstName().toCharArray());
  ByteBuffer nbBuffer = null;
  
  // length of first name
  try
  {
   nbBuffer = encoder.encode(nameBuffer);
  } 
  catch(CharacterCodingException e)
  {
   throw new ArithmeticException();
  }

  System.out.println(String.format("String [%1$s] #bytes = %2$s", emp.getFirstName(), nbBuffer.limit()));
  buffer.putInt(nbBuffer.limit());
  buffer.put(nbBuffer);

  // put lastname
  nameBuffer = CharBuffer.wrap(emp.getLastName().toCharArray());
  nbBuffer = null;
  
  // length of first name
  try
  {
   nbBuffer = encoder.encode(nameBuffer);   
  } 
  catch(CharacterCodingException e)
  {
   throw new ArithmeticException();
  }

  System.out.println(String.format("String [%1$s] #bytes = %2$s", emp.getLastName(), nbBuffer.limit()));
  buffer.putInt(nbBuffer.limit());
  buffer.put(nbBuffer);
  
  // salary
  buffer.putInt(emp.getSalary());
 }
}

&lt;/pre&gt;&lt;br /&gt;
The java client has a similar structure to the .NET app, except for the fact that the .NET app acts like the server, whereas the Java app is just a client. However that difference is not material to the current topic.&lt;br /&gt;
&lt;br /&gt;
The output of the java program is as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;String [John] #bytes = 4&lt;br /&gt;
String [Smith] #bytes = 5&lt;br /&gt;
# bytes = 25&lt;br /&gt;
#Bytes in output buffer: 0 limit = 25 pos = 0 remaining = 25&lt;br /&gt;
1&lt;br /&gt;
0&lt;br /&gt;
0&lt;br /&gt;
0&lt;br /&gt;
4&lt;br /&gt;
0&lt;br /&gt;
0&lt;br /&gt;
0&lt;br /&gt;
74&lt;br /&gt;
111&lt;br /&gt;
104&lt;br /&gt;
110&lt;br /&gt;
5&lt;br /&gt;
0&lt;br /&gt;
0&lt;br /&gt;
0&lt;br /&gt;
83&lt;br /&gt;
109&lt;br /&gt;
105&lt;br /&gt;
116&lt;br /&gt;
104&lt;br /&gt;
2&lt;br /&gt;
0&lt;br /&gt;
0&lt;br /&gt;
0&lt;br /&gt;
Number of bytes read: 25&lt;br /&gt;
FName Length: 4&lt;br /&gt;
LName Length: 5&lt;br /&gt;
ID: 1&lt;br /&gt;
First: John&lt;br /&gt;
Last: Smith&lt;br /&gt;
Salary: 2&lt;br /&gt;
Written bytes: 0&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
Now, let me talk about some important details of this application. First realize, that each platform has it's own way of how it represents primitive datatypes (bytes/integers/floats/characters) in a byte representation in memory. This concept is called &lt;a href="http://en.wikipedia.org/wiki/Endianness"&gt;Endianness&lt;/a&gt;. In the case of Java, the JRE is "Big Endian". While, on the CLR (i.e .NET) the byte representation is "Little Endian". So, when we convert data into a binary representation, we need to make sure that both sides do it the same way.&lt;br /&gt;
&lt;br /&gt;
Since .NET is "Little Endian" I decided to convert everything to Little Endian. On Java, this is very simple. Since I was using ByteBuffer to convert Java primitive types into bytes, I just set the ByteOrder on the ByteBuffer to be LITTLE_ENDIAN.&lt;br /&gt;
&lt;br /&gt;
The second thing to remember is about strings. When you are serializing objects that contain heterogenous datatypes, or types that vary in length, you need a way of distinguishing the end of one type from the begining of another. In the case of strings, I chose the Length. So, when I serialize a string, I first write out the length of the string, and then the entire string. The receiver first reads the length of the string, and then allocates a byte buffer for that string. It then reads in the actual bytes (upto the length of the string) into the array. Note, that the quantity written is not actually the length in Characters, but the length in bytes of the Encoded string.&lt;br /&gt;
&lt;br /&gt;
Which brings me to the final point. String conversion to Bytes can be done in various ways. I chose to use UTF-8 encoding. Again, the encoding used has to be the same on both the sides in order to be able to exchange the data correctly.&lt;br /&gt;
&lt;br /&gt;
I hope this was useful to you. In the next article, I will talk about using XML as a mechanism of transporting objects across heterogenous platforms.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6013019333081665053-8214252598153156082?l=ferozedaud.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/1Bpk2LNBQrBdS9lzFG08NMOsk_0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/1Bpk2LNBQrBdS9lzFG08NMOsk_0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/1Bpk2LNBQrBdS9lzFG08NMOsk_0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/1Bpk2LNBQrBdS9lzFG08NMOsk_0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FerozesMusingsOnTechnology/~4/5NTt8JwVYYM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ferozedaud.blogspot.com/feeds/8214252598153156082/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://ferozedaud.blogspot.com/2009/11/howto-serialize-data-from-object-from.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/8214252598153156082?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/8214252598153156082?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/FerozesMusingsOnTechnology/~3/5NTt8JwVYYM/howto-serialize-data-from-object-from.html" title="HOWTO: Serialize data from an object from .NET to Java using custom binary formatting." /><author><name>Feroze Daud</name><uri>https://profiles.google.com/106931323736171420480</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-htqG4D1zj34/AAAAAAAAAAI/AAAAAAAAAJM/o1zOCSZPA3c/s512-c/photo.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://ferozedaud.blogspot.com/2009/11/howto-serialize-data-from-object-from.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkEMQ3Y9fip7ImA9WxNbEko.&quot;"><id>tag:blogger.com,1999:blog-6013019333081665053.post-3912447413504685362</id><published>2009-11-01T17:26:00.000-08:00</published><updated>2009-11-15T00:44:42.866-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-15T00:44:42.866-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Socket" /><category scheme="http://www.blogger.com/atom/ns#" term="Network" /><category scheme="http://www.blogger.com/atom/ns#" term="Tracing" /><category scheme="http://www.blogger.com/atom/ns#" term="Authentication" /><category scheme="http://www.blogger.com/atom/ns#" term="System.Net" /><category scheme="http://www.blogger.com/atom/ns#" term="Logging" /><category scheme="http://www.blogger.com/atom/ns#" term="Debugging" /><category scheme="http://www.blogger.com/atom/ns#" term="ICMP" /><title>System.Net Links and HOWTOs</title><content type="html">A lot of people have blogged about System.NET tips and tricks. Esp from Microsoft, prior System.Net team members (&lt;a href="http://blogs.msdn.com/joncole"&gt;Jon Cole&lt;/a&gt;, &lt;a href="http://blogs.msdn.com/dgorti"&gt;Durgaprasad Gorti&lt;/a&gt;, &lt;a href="http://blogs.msdn.com/malarch/default.aspx"&gt;Malar Chinnusamy&lt;/a&gt;) have authored blog posts on how to do stuff with System.Net.&lt;br /&gt;
&lt;br /&gt;
Non microsoft folks have also stepped up to the plate. For eg, &lt;a href="http://nitoprograms.blogspot.com/"&gt;Stephen Cleary&lt;/a&gt; has written a very good concise blog on System.Net HOWTOs and FAQs.&lt;br /&gt;
&lt;br /&gt;
In this post,  I aim to categorize all of them and link them in one place, so that it will be easy to find for people who need information.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;FAQ&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://nitoprograms.blogspot.com/2009/04/tcpip-net-sockets-faq.html"&gt;Stephen Cleary's .NET TCP/IP Sockets FAQ&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://blogs.msdn.com/dgorti/archive/2005/10/29/486887.aspx"&gt;How to use a Network Monitor to debug your System.Net application&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://ferozedaud.blogspot.com/2009/08/tracing-with-systemnet.html"&gt;Creating a tracelog for your application&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://blogs.msdn.com/joncole/archive/2006/06/13/suggested-practices-for-proxy-configuration-when-using-system-net-httpwebrequest.aspx"&gt;Proxy Configuration Best Practices in System.Net&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Authentication&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://blogs.msdn.com/joncole/archive/2005/11/09/491009.aspx"&gt;Primer Part-1&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Message Framing&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://blogs.msdn.com/malarch/archive/2006/06/26/647993.aspx"&gt;Article on preserving message boundnaries&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://blogs.msdn.com/joncole/archive/2006/03/20/simple-message-framing-sample-for-tcp-socket.aspx"&gt;Synchronous Sample&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://blogs.msdn.com/joncole/archive/2006/04/25/simple-message-framing-sample-for-tcp-socket-part-2-asynchronous.aspx"&gt;Async sample&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://nitoprograms.blogspot.com/2009/04/message-framing.html"&gt;Another excellent sample on message framing by Stephen Cleary&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Cookies&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://blogs.msdn.com/dgorti/archive/2005/08/16/452347.aspx"&gt;How to use CookieCollection/CookieContainer&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;HTTP Expect-100 Continue Caveats&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The following blog &lt;a href="http://blogs.msdn.com/joncole/archive/2005/09/08/462659.aspx"&gt;post&lt;/a&gt; explains the consequences of having Expect100Continue=true for some servers.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Autoproxy support&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://blogs.msdn.com/mahjayar/archive/2005/08/04/447799.aspx"&gt;http://blogs.msdn.com/mahjayar/archive/2005/08/04/447799.aspx&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Socket Duplication&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Socket duplication is a new feature supported by the 2.0 version of the .NET framework. The following articles describe that in more detail, along with code samples.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://blogs.msdn.com/malarch/archive/2005/12/14/503884.aspx"&gt;Socket Duplication - Part 1&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://blogs.msdn.com/malarch/archive/2005/12/14/503884.aspx"&gt;Socket Duplication - Part 2&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;IPv6&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://blogs.msdn.com/malarch/archive/2005/11/19/494807.aspx"&gt;Configuring an IPv4 server to be able to receive connections from IPv6 clients&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;SMTPClient&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://www.systemnetmail.com/default.aspx"&gt;http://www.systemnetmail.com/default.aspx&lt;/a&gt; (FAQ for system.net.mail namespace and classes)&lt;br /&gt;
&lt;a href="http://blogs.msdn.com/mariya/archive/2006/06/15/633007.aspx"&gt;Sending mail to Gmail a/c with SMTPClient&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Socket Applications: Traceroute&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://ferozedaud.blogspot.com/2009/09/implementing-traceroute-with-systemnet.html"&gt;Part 1&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://ferozedaud.blogspot.com/2009/09/implementing-traceroute-with-systemnet_07.html"&gt;Part 2&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://ferozedaud.blogspot.com/2009/09/implementing-traceroute-with-systemnet_17.html"&gt;Part 3&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://ferozedaud.blogspot.com/2009/09/implementing-traceroute-with-systemnet_29.html"&gt;Part 4&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt; HOWTO send an object across the network, between a Java app and a .NET app, and back.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://ferozedaud.blogspot.com/2009/11/howto-serialize-data-from-object-from.html"&gt;http://ferozedaud.blogspot.com/2009/11/howto-serialize-data-from-object-from.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6013019333081665053-3912447413504685362?l=ferozedaud.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/h_oxvB4WybsTf4Tixw_e0g98IRI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/h_oxvB4WybsTf4Tixw_e0g98IRI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/h_oxvB4WybsTf4Tixw_e0g98IRI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/h_oxvB4WybsTf4Tixw_e0g98IRI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FerozesMusingsOnTechnology/~4/Yh0dqeL2YVE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ferozedaud.blogspot.com/feeds/3912447413504685362/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://ferozedaud.blogspot.com/2009/11/systemnet-links-and-howtos.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/3912447413504685362?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/3912447413504685362?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/FerozesMusingsOnTechnology/~3/Yh0dqeL2YVE/systemnet-links-and-howtos.html" title="System.Net Links and HOWTOs" /><author><name>Feroze Daud</name><uri>https://profiles.google.com/106931323736171420480</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-htqG4D1zj34/AAAAAAAAAAI/AAAAAAAAAJM/o1zOCSZPA3c/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://ferozedaud.blogspot.com/2009/11/systemnet-links-and-howtos.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUMRXw-eip7ImA9WxNVFEw.&quot;"><id>tag:blogger.com,1999:blog-6013019333081665053.post-1379230197265236639</id><published>2009-10-24T11:51:00.000-07:00</published><updated>2009-10-24T11:51:24.252-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-24T11:51:24.252-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Search" /><category scheme="http://www.blogger.com/atom/ns#" term="Lucene" /><title>Write your own search engine using Lucene</title><content type="html">Recently, I have been playing around with Lucene (&lt;a href="http://incubator.apache.org/lucene.net/"&gt;http://incubator.apache.org/lucene.net/&lt;/a&gt;. Lucene is an Open Source project, which is sponsored by the Apache foundation, that gives you all the components necessary to create your own search engine.&lt;br /&gt;
&lt;br /&gt;
I downloaded the latest build, which is versioned 2.0.004 and located at &lt;a href="http://incubator.apache.org/lucene.net/download/Incubating-Apache-Lucene.Net-2.0-004-11Mar07.bin.zip"&gt;http://incubator.apache.org/lucene.net/download/Incubating-Apache-Lucene.Net-2.0-004-11Mar07.bin.zip&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
To start off I wrote a small application that indexes all the INF files in my %WINDIR%\System32 directory, and allows me to search their contents.&lt;br /&gt;
&lt;br /&gt;
Here is an example of how the application works:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;Search...&lt;br /&gt;
You can enter....&lt;br /&gt;
filename|fullpath|lastmodified|contents&lt;br /&gt;
&gt;&gt; windows fullpath&lt;br /&gt;
Query: fullpath:windows&lt;br /&gt;
#hits: 8&lt;br /&gt;
----------------&lt;br /&gt;
Filename: homepage.inf&lt;br /&gt;
FullPath: c:\windows\system32\homepage.inf&lt;br /&gt;
Last-Modified: 8/10/2004 3:00:00 AM&lt;br /&gt;
----------------&lt;br /&gt;
Filename: ieuinit.inf&lt;br /&gt;
FullPath: c:\windows\system32\ieuinit.inf&lt;br /&gt;
Last-Modified: 6/29/2009 1:40:16 AM&lt;br /&gt;
----------------&lt;br /&gt;
Filename: mapisvc.inf&lt;br /&gt;
FullPath: c:\windows\system32\mapisvc.inf&lt;br /&gt;
Last-Modified: 4/14/2006 11:39:08 PM&lt;br /&gt;
----------------&lt;br /&gt;
Filename: mmdriver.inf&lt;br /&gt;
FullPath: c:\windows\system32\mmdriver.inf&lt;br /&gt;
Last-Modified: 8/10/2004 3:00:00 AM&lt;br /&gt;
----------------&lt;br /&gt;
Filename: msxmlx.inf&lt;br /&gt;
FullPath: c:\windows\system32\msxmlx.inf&lt;br /&gt;
Last-Modified: 8/6/2003 10:15:48 AM&lt;br /&gt;
----------------&lt;br /&gt;
Filename: pid.inf&lt;br /&gt;
FullPath: c:\windows\system32\pid.inf&lt;br /&gt;
Last-Modified: 6/20/2007 10:52:36 PM&lt;br /&gt;
----------------&lt;br /&gt;
Filename: $ncsp$.inf&lt;br /&gt;
FullPath: c:\windows\system32\$ncsp$.inf&lt;br /&gt;
Last-Modified: 9/23/2005 6:50:22 AM&lt;br /&gt;
----------------&lt;br /&gt;
Filename: $winnt$.inf&lt;br /&gt;
FullPath: c:\windows\system32\$winnt$.inf&lt;br /&gt;
Last-Modified: 9/27/2005 8:46:09 PM&lt;br /&gt;
Search...&lt;br /&gt;
You can enter....&lt;br /&gt;
filename|fullpath|lastmodified|contents&lt;br /&gt;
&gt;&gt; msxml contents&lt;br /&gt;
Query: contents:msxml&lt;br /&gt;
#hits: 1&lt;br /&gt;
----------------&lt;br /&gt;
Filename: msxmlx.inf&lt;br /&gt;
FullPath: c:\windows\system32\msxmlx.inf&lt;br /&gt;
Last-Modified: 8/6/2003 10:15:48 AM&lt;br /&gt;
Search...&lt;br /&gt;
You can enter....&lt;br /&gt;
filename|fullpath|lastmodified|contents&lt;br /&gt;
&gt;&gt; &lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
Here is the code for the application.&lt;br /&gt;
&lt;br /&gt;
&lt;pre name="code" class="csharp"&gt;using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lucene.Net;
using Lucene.Net.Analysis;
using Lucene.Net.Analysis.Standard;
using Lucene.Net.Documents;
using Lucene.Net.Store;
using Lucene.Net.Util;
using Lucene.Net.Index;
using Lucene.Net.Search;
using Lucene.Net.QueryParsers;
using sdir = System.IO.Directory;
using LDirectory = Lucene.Net.Store.Directory;
using System.IO;

namespace searchtest
{
    class Program
    {
        static void Main(string[] args)
        {
            Analyzer analyzer = new StandardAnalyzer();
            LDirectory directory = FSDirectory.GetDirectory("/index.bin", true);
            //Directory directory = new RAMDirectory();
            IndexWriter writer = new IndexWriter(directory, analyzer, true);
            writer.SetMaxFieldLength(25000);

            String [] infs = sdir.GetFiles(@"c:\windows\system32", "*.inf");
            foreach (String inf in infs)
            {
                FileInfo fi = new FileInfo(inf);
                Document doc = new Document();
                doc.Add(new Field("filename", fi.Name, Field.Store.YES, Field.Index.TOKENIZED));
                doc.Add(new Field("fullpath", fi.FullName, Field.Store.YES, Field.Index.TOKENIZED));
                doc.Add(new Field("lastmodified", DateField.DateToString(fi.LastWriteTimeUtc), Field.Store.YES, Field.Index.TOKENIZED));

                using (StreamReader sr = new StreamReader(inf))
                {
                    String text = sr.ReadToEnd();
                    doc.Add(new Field("contents", text, Field.Store.YES,
                        Field.Index.TOKENIZED));
                    writer.AddDocument(doc);
                }
            }

            writer.Close();

            // Now search the index:
            IndexSearcher isearcher = new IndexSearcher(directory);

            while (true)
            {
                Console.WriteLine("Search...");
                Console.WriteLine("You can enter....");
                Console.WriteLine("filename|fullpath|lastmodified|contents");

                Console.Write("&gt;&gt; ");
                String cmd = Console.ReadLine();

                if (cmd == null || cmd.Length == 0)
                    break;

                String fieldname = "contents";
                String predicate = null;

                if (cmd.StartsWith("!"))
                {
                    int index = cmd.LastIndexOf("\"");
                    predicate = cmd.Substring(2, index-2);
                    fieldname = cmd.Substring(index + 1);
                }
                else if (cmd.StartsWith("\""))
                {
                    int index = cmd.LastIndexOf("\"");
                    if (index != -1)
                    {
                        predicate = cmd.Substring(1, index-1);
                        if (++index &lt; cmd.Length)
                        {
                            fieldname = cmd.Substring(index);
                        }
                    }
                }
                else
                {
                    String[] tokens = cmd.Split();
                    if (tokens.Length == 2)
                    {
                        predicate = tokens[0];
                        fieldname = tokens[1];
                    }
                    else if (tokens.Length == 1)
                    {
                        predicate = tokens[0];
                    }
                    else
                    {
                        Console.WriteLine("ERROR:");
                        continue;
                    }
                }

                // Parse a simple query that searches for "text":
                QueryParser parser = new QueryParser(fieldname, analyzer);
                Query query = null;

                try
                {
                    query = parser.Parse(predicate);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    continue;
                }


                Hits hits = isearcher.Search(query);
                Console.WriteLine("Query: {0}", query.ToString());
                Console.WriteLine("#hits: {0}", hits.Length());
                // Iterate through the results:
                for (int i = 0; i &lt; hits.Length(); i++)
                {
                    Console.WriteLine("----------------");
                    Document hitDoc = hits.Doc(i);
                    Console.WriteLine("Filename: {0}", hitDoc.Get("filename"));
                    Console.WriteLine("FullPath: {0}", hitDoc.Get("fullpath"));
                    Field f = hitDoc.GetField("lastmodified");
                    Console.WriteLine("Last-Modified: {0}", DateField.StringToDate(hitDoc.Get("lastmodified")));
                    //Console.WriteLine(hitDoc.Get("contents"));
                }
            }
            isearcher.Close();
            directory.Close(); 
        }
    }
}
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6013019333081665053-1379230197265236639?l=ferozedaud.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/0_JRiEzDs6iQwPMW9cM4Q9d6qNs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0_JRiEzDs6iQwPMW9cM4Q9d6qNs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/0_JRiEzDs6iQwPMW9cM4Q9d6qNs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0_JRiEzDs6iQwPMW9cM4Q9d6qNs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FerozesMusingsOnTechnology/~4/Xoq1ZK9YD2A" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ferozedaud.blogspot.com/feeds/1379230197265236639/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://ferozedaud.blogspot.com/2009/10/write-your-own-search-engine-using.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/1379230197265236639?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/1379230197265236639?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/FerozesMusingsOnTechnology/~3/Xoq1ZK9YD2A/write-your-own-search-engine-using.html" title="Write your own search engine using Lucene" /><author><name>Feroze Daud</name><uri>https://profiles.google.com/106931323736171420480</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-htqG4D1zj34/AAAAAAAAAAI/AAAAAAAAAJM/o1zOCSZPA3c/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://ferozedaud.blogspot.com/2009/10/write-your-own-search-engine-using.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkABQ3s6cCp7ImA9WxNXFU4.&quot;"><id>tag:blogger.com,1999:blog-6013019333081665053.post-6087566284875246349</id><published>2009-10-02T19:59:00.000-07:00</published><updated>2009-10-02T19:59:12.518-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-02T19:59:12.518-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Tracing" /><category scheme="http://www.blogger.com/atom/ns#" term="Authentication" /><category scheme="http://www.blogger.com/atom/ns#" term="System.Net" /><category scheme="http://www.blogger.com/atom/ns#" term="HttpWebRequest" /><category scheme="http://www.blogger.com/atom/ns#" term="NTLM" /><title>NTLM auth fails with HttpWebRequest/WebClient, but passes with IE</title><content type="html">On public newsgroups, I have seen a lot of postings where people complained that their managed code application, written with HttpWebRequest, and using NTLM auth to talk to a server, would fail. However, Internet explorer running on the same machine would work fine.&lt;br /&gt;
&lt;br /&gt;
Here are some of the threads that show this problem:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://social.msdn.microsoft.com/Forums/en-US/netfxnetcom/thread/a4aba6c5-6180-441e-ab60-95347fcdc051"&gt;http://social.msdn.microsoft.com/Forums/en-US/netfxnetcom/thread/a4aba6c5-6180-441e-ab60-95347fcdc051&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
In order to root cause this issue, you need to enable logging using System.Net tracelog (&lt;a href="http://ferozedaud.blogspot.com/2009/08/tracing-with-systemnet.html"&gt;http://ferozedaud.blogspot.com/2009/08/tracing-with-systemnet.html&lt;/a&gt;) and see the trace. If you see that the client fails with a NotSupported error, when trying to compose a Type2 message (using the response to the previous Type1 message sent by the client).&lt;br /&gt;
&lt;br /&gt;
The second variable here is the operating system on both the client and server. If the OS on the client is &gt;= Vista (for eg, any flavor of Vista or Windows7) and the OS on the server is a version before Vista, then there was a change in the way NTLM works. In vista and later operating systems, NTLM by default now requires 128bit encryption, whereas the prior OS did not.&lt;br /&gt;
&lt;br /&gt;
Ok. So why does IE work on the same machine, and NTLM doesnt?&lt;br /&gt;
&lt;br /&gt;
The difference is the way in which both use the NTLM SSPI package.&lt;br /&gt;
&lt;br /&gt;
When HttpWebRequest uses the package, it asks for NTLMSSP_NEGOTIATE_SEAL and NTLM_NEGOTIATE_SIGN capabilities. This requres encryption. Since 128bit encryption is now required by the OS, this means that the server also has to support 128bit. If the server doesnt, then the authentication will fail.&lt;br /&gt;
&lt;br /&gt;
IE does not ask for SEAL|SIGN capabilities when composing the Type2 message. So, even if the server does not support 128bit encryption, the authentication can still work.&lt;br /&gt;
&lt;br /&gt;
For more details, refer to this thread on stackoverflow:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://stackoverflow.com/questions/1443617/407-authentication-required-no-challenge-sent/1482442#1482442"&gt;http://stackoverflow.com/questions/1443617/407-authentication-required-no-challenge-sent/1482442#1482442&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Note, that even WindowsXP/Server2003 supports 128bit encryption, just not out of the box. And on Windows7/Vista, even though 128bit is default, it can be changed by modifying the security policy. However, that might now always be possible, esp if the machine is on a domain where the policy is administered by the Domain Admin.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6013019333081665053-6087566284875246349?l=ferozedaud.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/OO3C-8n0s5T6w21whZh7-u3PMWQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/OO3C-8n0s5T6w21whZh7-u3PMWQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/OO3C-8n0s5T6w21whZh7-u3PMWQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/OO3C-8n0s5T6w21whZh7-u3PMWQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FerozesMusingsOnTechnology/~4/xJ1kGxMgL2c" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ferozedaud.blogspot.com/feeds/6087566284875246349/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://ferozedaud.blogspot.com/2009/10/ntlm-auth-fails-with.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/6087566284875246349?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/6087566284875246349?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/FerozesMusingsOnTechnology/~3/xJ1kGxMgL2c/ntlm-auth-fails-with.html" title="NTLM auth fails with HttpWebRequest/WebClient, but passes with IE" /><author><name>Feroze Daud</name><uri>https://profiles.google.com/106931323736171420480</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-htqG4D1zj34/AAAAAAAAAAI/AAAAAAAAAJM/o1zOCSZPA3c/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://ferozedaud.blogspot.com/2009/10/ntlm-auth-fails-with.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU4NSH8yfSp7ImA9WxNXEko.&quot;"><id>tag:blogger.com,1999:blog-6013019333081665053.post-4390789571770923998</id><published>2009-09-29T18:26:00.000-07:00</published><updated>2009-09-29T18:26:39.195-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-29T18:26:39.195-07:00</app:edited><title>Implementing Traceroute with System.Net - Part IV</title><content type="html">In the previous parts, I showed how to implement traceroute using System.Net.Sockets.  We used the Socket class to create a Raw socket, and use that to do a traceroute.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://ferozedaud.blogspot.com/2009/09/implementing-traceroute-with-systemnet_17.html"&gt;Implementing Traceroute with System.Net Part III&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://ferozedaud.blogspot.com/2009/09/implementing-traceroute-with-systemnet_07.html"&gt;Implementing Traceroute with System.Net Part II&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://ferozedaud.blogspot.com/2009/09/implementing-traceroute-with-systemnet.html"&gt;Implementing Traceroute with System.Net Part I&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
It turns out, that System.Net.NetworkInformation  already has a &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.networkinformation.ping.aspx"&gt;Ping&lt;/a&gt; class, that encapsulates all the functionality of sending ICMP ECHO requests and processing replies. It has the necessary switches to tweak the TTL settings as well.&lt;br /&gt;
&lt;br /&gt;
I wrote a small program to demonstrate  how we can do a Traceroute using the Ping class.&lt;br /&gt;
&lt;br /&gt;
&lt;pre name="code" class="csharp"&gt;using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;

namespace PingClassTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Ping pinger = new Ping();
            String data = "0123456789ABCDEF";
            byte[] buffer = Encoding.ASCII.GetBytes(data);
            PingOptions options = new PingOptions();

            IPHostEntry target = Dns.GetHostEntry(args[0]);
            bool isDestination = false;
            for(int i = 1; i &lt;= 30; i++)
            {
                String intermediateHost = null;
                for (int j = 0; j &lt; 3; j++)
                {
                    options.Ttl = i;
                    PingReply reply = pinger.Send(target.AddressList[0], 30, buffer, options);
                    switch (reply.Status)
                    {
                        case IPStatus.TimedOut:
                        case IPStatus.TtlExpired:
                        case IPStatus.Success:
                            Console.Write("&lt;{0}ms\t", reply.RoundtripTime);
                            if (reply.Address.Equals(target.AddressList[0]))
                            {
                                isDestination = true;
                            }
                            intermediateHost = reply.Address.ToString();
                            break;
                        default:
                            Console.Write("*\t");
                            break;

                    }
                }

                Console.WriteLine("\t{0}", intermediateHost);

                if (isDestination)
                {
                    break;
                }
            }javascript:void(0)
        }

        pinger.Dispose();
    }
}
&lt;/pre&gt;

The output of this program, when pinging www.yahoo.com is as follows:

&lt;pre&gt;&amp;lt;0ms    &amp;lt;0ms    &amp;lt;0ms            192.168.1.1
&amp;lt;0ms    &amp;lt;0ms    &amp;lt;0ms            98.117.116.1
&amp;lt;0ms    &amp;lt;0ms    &amp;lt;0ms            130.81.138.218
&amp;lt;0ms    &amp;lt;0ms    &amp;lt;0ms            130.81.28.166
&amp;lt;0ms    &amp;lt;0ms    &amp;lt;0ms            130.81.17.56
&amp;lt;0ms    &amp;lt;0ms    &amp;lt;0ms            130.81.17.231
&amp;lt;0ms    &amp;lt;0ms    &amp;lt;0ms            130.81.14.90
&amp;lt;0ms    &amp;lt;0ms    &amp;lt;0ms            216.115.107.57
&amp;lt;0ms    &amp;lt;0ms    &amp;lt;0ms            209.131.32.23
&amp;lt;27ms   &amp;lt;26ms   &amp;lt;26ms           209.131.36.158
Press any key to continue . . .
&lt;/pre&gt;
As you can see, this program gives the exact same functionality as the program that we wrote using the Socket class.

The &lt;a href="http://msdn.microsoft.com/en-us/library/system.net.networkinformation.ping.aspx"&gt;Ping&lt;/a&gt; class also supports asynchronous functionality which makes it very useful for high performance applications.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6013019333081665053-4390789571770923998?l=ferozedaud.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/RcfLKQNiatA1bWdO1IZydOP27Wo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/RcfLKQNiatA1bWdO1IZydOP27Wo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/RcfLKQNiatA1bWdO1IZydOP27Wo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/RcfLKQNiatA1bWdO1IZydOP27Wo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FerozesMusingsOnTechnology/~4/lujQKWAZ2d4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ferozedaud.blogspot.com/feeds/4390789571770923998/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://ferozedaud.blogspot.com/2009/09/implementing-traceroute-with-systemnet_29.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/4390789571770923998?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/4390789571770923998?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/FerozesMusingsOnTechnology/~3/lujQKWAZ2d4/implementing-traceroute-with-systemnet_29.html" title="Implementing Traceroute with System.Net - Part IV" /><author><name>Feroze Daud</name><uri>https://profiles.google.com/106931323736171420480</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-htqG4D1zj34/AAAAAAAAAAI/AAAAAAAAAJM/o1zOCSZPA3c/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://ferozedaud.blogspot.com/2009/09/implementing-traceroute-with-systemnet_29.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUEERXk5eyp7ImA9WxNXEks.&quot;"><id>tag:blogger.com,1999:blog-6013019333081665053.post-5911814825485906629</id><published>2009-09-17T18:25:00.000-07:00</published><updated>2009-09-29T16:40:04.723-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-29T16:40:04.723-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Socket" /><category scheme="http://www.blogger.com/atom/ns#" term="Network" /><category scheme="http://www.blogger.com/atom/ns#" term="Tracing" /><category scheme="http://www.blogger.com/atom/ns#" term="System.Net" /><category scheme="http://www.blogger.com/atom/ns#" term="ICMP" /><title>Implementing Traceroute with System.Net - Part III</title><content type="html">In the previous part &lt;a href="http://ferozedaud.blogspot.com/2009/09/implementing-traceroute-with-systemnet_07.html"&gt;http://ferozedaud.blogspot.com/2009/09/implementing-traceroute-with-systemnet_07.html&lt;/a&gt; I showed a simple implementation of traceroute, that built upon my earlier implementation of Ping.&lt;br /&gt;
&lt;br /&gt;
As promised, in this article, we will see how to make the utility more robust.&lt;br /&gt;
&lt;br /&gt;
One of the things I didnt like about the previous implementation, was that there was no verification of the received request packet. The implementation was not verifying whether the type of the response was correct - an ICMP Echo request should elicit an ICMP Echo response (see the ICMP RFC at &lt;a href="http://www.ietf.org/rfc/rfc0792.txt"&gt;http://www.ietf.org/rfc/rfc0792.txt&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
So, we add the code for verifying that. According to the RFC, the Echo reply message has a Type Field = 0. Also, since we are using the TTL mechanism for detecting hosts along the route to the destination, we expect that every host but the final one, will reply with a ICMP Time Exceeded message, which has a Message Type = 11.&lt;br /&gt;
&lt;br /&gt;
Also, the other issue with the tool, is that it does not resolve the IPAddress of the intermediate hosts. In a traceroute output, we are mostly interested in the hostnames of the intermediate routers, and not just the IP address. So, we will add that capability as well.&lt;br /&gt;
&lt;br /&gt;
With these changes, here is the changed code. I have only put the changes to the while(true) loop in my original implementation.&lt;br /&gt;
&lt;pre name="code" class="csharp"&gt;while (true)
{
Console.Write("{0}", hop);
bool allTimedOut = true;
for (int i = 0; i &amp;lt; 3; i++)
{
ICMP_PACKET packet = ICMP_PACKET.CreateRequestPacket(111, 222, data);

IPEndPoint epRemote = new IPEndPoint(ipTarget, 0);

pingSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.IpTimeToLive, hop);


stopWatch.Start();
pingSocket.SendTo(packet.Serialize(), epRemote);



byte[] receiveData = new byte[1024];
int read = 0;
try
{
epResponse = new IPEndPoint(0, 0);
read = pingSocket.ReceiveFrom(receiveData, ref epResponse);
stopWatch.Stop();

ICMP_PACKET recvPacket = new ICMP_PACKET(receiveData, 20, read);

ipepResponse = epResponse as IPEndPoint;

if (recvPacket.PacketType == 11)
{
// this is an ICMP Time exceeded message
if (ipepResponse.Address.Equals(ipTarget))
{
// do not expect an ICMP Time Exceeded message from the
// final destination.
Console.Error.Write("\t!!");
}
}
else if (recvPacket.PacketType == 0)
{
// this is an ICMP Echo reply message
// validate that this is coming from the destination host.
if (!ipepResponse.Address.Equals(ipTarget))
{
// do not expect an ICMP Time Exceeded message from the
// final destination.
Console.Error.Write("\t!!");
}
}

Console.Write("\t&amp;lt;&lt;{0}ms", stopWatch.ElapsedMilliseconds);
allTimedOut = false;
}
catch (SocketException e)
{
Console.Write("\t*");
}
}

if (allTimedOut)
{
Console.WriteLine("\tRequest timed out");
}
else
{
String intermediateHost = null;
// now try to resolve the IPAddress
try
{
IPHostEntry hostEntry = Dns.GetHostEntry(ipepResponse.Address);
intermediateHost = hostEntry.HostName;
}
catch (SocketException e)
{
}

Console.WriteLine("\t{0} {1}", ((IPEndPoint)epResponse).Address.ToString(), intermediateHost);

}
++hop;

ipepResponse = epResponse as IPEndPoint;
if (hop &amp;gt; maxHops || ipepResponse.Address.Equals(ipTarget))
{
break;
}
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
In the next part, I will throw some ideas out there, on how this can be extended even more.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6013019333081665053-5911814825485906629?l=ferozedaud.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/8tudZo5w1nWcYhiwMEnAEmRLZAQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8tudZo5w1nWcYhiwMEnAEmRLZAQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/8tudZo5w1nWcYhiwMEnAEmRLZAQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8tudZo5w1nWcYhiwMEnAEmRLZAQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FerozesMusingsOnTechnology/~4/umhQubO5hYk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ferozedaud.blogspot.com/feeds/5911814825485906629/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://ferozedaud.blogspot.com/2009/09/implementing-traceroute-with-systemnet_17.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/5911814825485906629?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/5911814825485906629?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/FerozesMusingsOnTechnology/~3/umhQubO5hYk/implementing-traceroute-with-systemnet_17.html" title="Implementing Traceroute with System.Net - Part III" /><author><name>Feroze Daud</name><uri>https://profiles.google.com/106931323736171420480</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-htqG4D1zj34/AAAAAAAAAAI/AAAAAAAAAJM/o1zOCSZPA3c/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://ferozedaud.blogspot.com/2009/09/implementing-traceroute-with-systemnet_17.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0YGQXszeyp7ImA9WxNRF0w.&quot;"><id>tag:blogger.com,1999:blog-6013019333081665053.post-6545468530860914064</id><published>2009-09-11T18:09:00.001-07:00</published><updated>2009-09-11T18:32:00.583-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-11T18:32:00.583-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Network" /><category scheme="http://www.blogger.com/atom/ns#" term="Tracing" /><category scheme="http://www.blogger.com/atom/ns#" term="Logging" /><category scheme="http://www.blogger.com/atom/ns#" term="Debugging" /><title>Network Programmers Toolchest</title><content type="html">In this post, I want to talk about some of the tools that a programmer doing network programmer might want to learn, in order to do his job better.&lt;br /&gt;&lt;br /&gt;First, let us talk about &lt;span style="font-weight:bold;"&gt;logging tools&lt;/span&gt;. No matter which library you use, whether it is System.Net from .NET framework, or CommonsHTTP from the Apache Commons project, you need to have a way of enabling logging to see what is going on in the library.&lt;br /&gt;&lt;br /&gt;If you are using System.Net, then you can enable logging using the Logging facility provided in the .NET framework.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ferozedaud.blogspot.com/2009/08/tracing-with-systemnet.html"&gt;http://ferozedaud.blogspot.com/2009/08/tracing-with-systemnet.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For Apache ComonsHttp library, you can enable logging using the Log4J  logging library:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://logging.apache.org/log4j/index.html"&gt;http://logging.apache.org/log4j/index.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Next, you need a way to capture network traffic in order to see what is going on in the network. Many tools exist that can allow you to do that. I prefer to use Wireshark, but on windows, Netmon is also pretty good.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.wireshark.org"&gt;http://www.wireshark.org&lt;/a&gt;&lt;br /&gt;&lt;a href="http://blogs.technet.com/netmon/"&gt;http://blogs.technet.com/netmon&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Imagine that you are trying to write code that can simulate loggin in to a website. For eg, &lt;a href="http://www.facebook.com"&gt;Facebook&lt;/a&gt; or a line of business application. However, it isnt working - you tried using logging but cant seem to get to the problem.  In this case, you might want to use a browser and try out the same scenario,  and see what the browser is doing differently.&lt;br /&gt;&lt;br /&gt;You can do that by using Wireshark/Netmon to sniff the browser session, but it is not very user friendly. Plus, if the session is encrypted (HTTPS) you cannot even make sense of the network sniff.&lt;br /&gt;&lt;br /&gt;In this case, it helps to have a browser extension that can sniff  the outgoing requests and incoming responses for you. I like to use Firebug on Firefox, and there are equivalent extensions for Internet Explorer as well.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://getfirebug.com/"&gt;http://getfirebug.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here are the ones for Internet Explorer.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.fiddler2.com/Fiddler2/version.asp"&gt;http://www.fiddler2.com/Fiddler2/version.asp&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.httpwatch.com/"&gt;http://www.httpwatch.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Readers: Do you have any favorite tools that I have not covered here? I would like to know about them. Add a comment to this post with the information.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6013019333081665053-6545468530860914064?l=ferozedaud.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/O5uyvQ71362TejOMXsuJoOvkIqY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/O5uyvQ71362TejOMXsuJoOvkIqY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/O5uyvQ71362TejOMXsuJoOvkIqY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/O5uyvQ71362TejOMXsuJoOvkIqY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FerozesMusingsOnTechnology/~4/sQL10WQ3uJE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ferozedaud.blogspot.com/feeds/6545468530860914064/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://ferozedaud.blogspot.com/2009/09/network-programmers-toolchest.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/6545468530860914064?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/6545468530860914064?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/FerozesMusingsOnTechnology/~3/sQL10WQ3uJE/network-programmers-toolchest.html" title="Network Programmers Toolchest" /><author><name>Feroze Daud</name><uri>https://profiles.google.com/106931323736171420480</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-htqG4D1zj34/AAAAAAAAAAI/AAAAAAAAAJM/o1zOCSZPA3c/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://ferozedaud.blogspot.com/2009/09/network-programmers-toolchest.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMGRXc5eip7ImA9WxNRFUQ.&quot;"><id>tag:blogger.com,1999:blog-6013019333081665053.post-728934304991483061</id><published>2009-09-10T08:55:00.000-07:00</published><updated>2009-09-10T09:00:24.922-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-10T09:00:24.922-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Authentication" /><category scheme="http://www.blogger.com/atom/ns#" term="System.Net" /><category scheme="http://www.blogger.com/atom/ns#" term="HttpWebRequest" /><category scheme="http://www.blogger.com/atom/ns#" term="NTLM" /><category scheme="http://www.blogger.com/atom/ns#" term="Microsoft" /><title>The case of multiple NTLM challenges with IIS7</title><content type="html">A reader posed a question on &lt;a href="http://stackoverflow.com"&gt;Stack Overflow&lt;/a&gt; about a problem with authentication. The scenario was as follows:&lt;br /&gt;&lt;br /&gt;This was a typical 3-tier application, in which the middle-tier (ASP.NET web server) was making a HttpWebRequest to a backend II7 server that required authentication.&lt;br /&gt;&lt;br /&gt;When authentication method was set to Digest/Basic/Negotiate, the server worked fine, and the authentication succeeded. However, if the auth method was set to NTLM, the server started to challenge twice.&lt;br /&gt;&lt;br /&gt;The reader investigate this, and found that this was caused by a Microsoft Security Update &lt;a href="http://support.microsoft.com/kb/957097"&gt;http://support.microsoft.com/kb/957097&lt;/a&gt;. Also, he came up with a solution for the problem.&lt;br /&gt;&lt;br /&gt;Read more about the problem and it's solution at: &lt;a href="http://www.tinyint.com/index.php/2009/08/24/401-error-on-httpwebrequest-with-ntlm-authentication/"&gt;http://www.tinyint.com/index.php/2009/08/24/401-error-on-httpwebrequest-with-ntlm-authentication/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6013019333081665053-728934304991483061?l=ferozedaud.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/yObh2KO8l1c-ym3vu7EF8amoJk4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yObh2KO8l1c-ym3vu7EF8amoJk4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/yObh2KO8l1c-ym3vu7EF8amoJk4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yObh2KO8l1c-ym3vu7EF8amoJk4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FerozesMusingsOnTechnology/~4/1oLd2cgVtZo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ferozedaud.blogspot.com/feeds/728934304991483061/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://ferozedaud.blogspot.com/2009/09/case-of-multiple-ntlm-challenges-with.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/728934304991483061?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/728934304991483061?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/FerozesMusingsOnTechnology/~3/1oLd2cgVtZo/case-of-multiple-ntlm-challenges-with.html" title="The case of multiple NTLM challenges with IIS7" /><author><name>Feroze Daud</name><uri>https://profiles.google.com/106931323736171420480</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-htqG4D1zj34/AAAAAAAAAAI/AAAAAAAAAJM/o1zOCSZPA3c/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://ferozedaud.blogspot.com/2009/09/case-of-multiple-ntlm-challenges-with.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkYCSHsyeyp7ImA9WxNXEks.&quot;"><id>tag:blogger.com,1999:blog-6013019333081665053.post-6590815440010956193</id><published>2009-09-07T19:09:00.001-07:00</published><updated>2009-09-29T16:49:29.593-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-29T16:49:29.593-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="System.Net" /><category scheme="http://www.blogger.com/atom/ns#" term="Microsoft" /><category scheme="http://www.blogger.com/atom/ns#" term="Unified Messaging" /><title>Implementing Traceroute with System.Net: Part-II</title><content type="html">In this part, we will implement traceroute according to the principles we discussed in the last post:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://ferozedaud.blogspot.com/2009/09/implementing-traceroute-with-systemnet.html"&gt;http://ferozedaud.blogspot.com/2009/09/implementing-traceroute-with-systemnet.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
First, start with the code for Ping, which is at &lt;a href="http://blogs.msdn.com/feroze_daud/archive/2005/10/26/485372.aspx"&gt;http://blogs.msdn.com/feroze_daud/archive/2005/10/26/485372.aspx&lt;/a&gt; and modify the Main() method as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;pre name="code" class="csharp"&gt;    static void Main(string[] args)
    {

        if (args.Length != 1)
        {
            Usage();
        }



        if (0 == String.Compare(args[0], "/?", true, CultureInfo.InvariantCulture)

        || 0 == String.Compare(args[0], "-h", true, CultureInfo.InvariantCulture)

        || 0 == String.Compare(args[0], "-?", true, CultureInfo.InvariantCulture))
        {
            Usage();
        }

        string target = args[0];

        IPAddress[] heTarget = Dns.GetHostAddresses(target);

        IPAddress ipTarget = null;

        foreach (IPAddress ip in heTarget)
        {

            if (ip.AddressFamily == AddressFamily.InterNetwork)
            {
                ipTarget = ip;
                break;
            }
        }



        IPAddress[] heSource = Dns.GetHostAddresses(Dns.GetHostName());

        IPAddress ipSource = null;

        foreach (IPAddress ip in heSource)
        {
            byte[] addressBytes = ip.GetAddressBytes();
            if (addressBytes[0] == 169 &amp;&amp; addressBytes[1] == 254)
            {
                continue;
            }
            if (ip.AddressFamily == AddressFamily.InterNetwork)
            {
                ipSource = ip;
                break;
            }
        }

        IPEndPoint epLocal = new IPEndPoint(ipSource, 0);

        Socket pingSocket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);

        pingSocket.Bind(epLocal);

        byte[] data = Encoding.ASCII.GetBytes("1234567890abcdef");

        Console.WriteLine("Ping {0}({1}) with {2} bytes of data...", target, ipTarget.ToString(), data.Length);

        Console.WriteLine();

        int hop = 1;
        int maxHops = 30;

        pingSocket.ReceiveTimeout = 30;
        System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();
        EndPoint epResponse = (EndPoint)new IPEndPoint(0, 0);

        while (true)
        {
            Console.Write("{0}", hop);
            bool allTimedOut = true;
            for (int i = 0; i &amp;lt; 3; i++)
            {
                ICMP_PACKET packet = ICMP_PACKET.CreateRequestPacket(111, 222, data);

                IPEndPoint epRemote = new IPEndPoint(ipTarget, 0);

                pingSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.IpTimeToLive, hop);


                stopWatch.Start();
                pingSocket.SendTo(packet.Serialize(), epRemote);

                byte[] receiveData = new byte[1024];
                int read = 0;
                try
                {
                    epResponse = new IPEndPoint(0, 0);
                    read = pingSocket.ReceiveFrom(receiveData, ref epResponse);
                    stopWatch.Stop();
                    ICMP_PACKET recvPacket = new ICMP_PACKET(receiveData, 20, read);

                    Console.Write("\&amp;lt;&lt;{0}ms", stopWatch.ElapsedMilliseconds);
                    allTimedOut = false;
                }
                catch (SocketException e)
                {
                    Console.Write("\t*");
                }
            }

            if (allTimedOut)
            {
                Console.WriteLine("\tRequest timed out");
            }
            else
            {
                Console.WriteLine("\t{0}", ((IPEndPoint)epResponse).Address.ToString());
            }
            ++hop;

            IPEndPoint ipepResponse = epResponse as IPEndPoint;
            if (hop &amp;gt; maxHops || ipepResponse.Address.Equals(ipTarget))
            {
                break;
            }
        }

        pingSocket.Close();
    }

&lt;/pre&gt;



As discussed earlier, we have now put a loop around the actual Socket.SendTo() call. This loop will run three times. We will continue sending the packet until we reach 30 hops max, or we have reached the destination.

As you have noticed, since we did all the heavy lifting in the Ping program, all we had to do here, was to set the &lt;b&gt;TimeToLive&lt;/b&gt; Socket option so that the routers/gateways on the path to the destination respond with a "Time Exceeded" message.

When I run it on my machine, here is the output:

&lt;pre&gt;C:\&gt;traceroute.exe www.yahoo.com
Ping www.yahoo.com(209.131.36.158) with 16 bytes of data...

1       &amp;lt;0ms    &amp;lt;1ms    &amp;lt;1ms    192.168.1.1
2       &amp;lt;5ms    &amp;lt;10ms   &amp;lt;14ms   &amp;lt;Address removed&amp;gt;
3       &amp;lt;18ms   &amp;lt;23ms   &amp;lt;27ms   &amp;lt;Address removed&amp;gt;
4       &amp;lt;33ms   &amp;lt;38ms   &amp;lt;43ms   &amp;lt;Address removed&amp;gt;
5       &amp;lt;68ms   &amp;lt;92ms   &amp;lt;116ms  &amp;lt;Address removed&amp;gt;
6       &amp;lt;143ms  &amp;lt;171ms  &amp;lt;197ms  &amp;lt;Address removed&amp;gt;
7       &amp;lt;223ms  &amp;lt;250ms  &amp;lt;276ms  &amp;lt;Address removed&amp;gt;
8       &amp;lt;304ms  &amp;lt;331ms  &amp;lt;365ms  &amp;lt;Address removed&amp;gt;
9       &amp;lt;391ms  &amp;lt;417ms  &amp;lt;445ms  &amp;lt;Address removed&amp;gt;
10      &amp;lt;473ms  &amp;lt;510ms  &amp;lt;538ms  &amp;lt;Address removed&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Note, that I have removed the actual IPAddresses from the output, for privacy reasons.&lt;br /&gt;
&lt;br /&gt;
In the next part, we will discuss how we can make this utility more robust.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6013019333081665053-6590815440010956193?l=ferozedaud.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/b2ylJvNLMP_uzx_m9JXIMA76Wn8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/b2ylJvNLMP_uzx_m9JXIMA76Wn8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/b2ylJvNLMP_uzx_m9JXIMA76Wn8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/b2ylJvNLMP_uzx_m9JXIMA76Wn8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FerozesMusingsOnTechnology/~4/hYoeEqFVEp8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ferozedaud.blogspot.com/feeds/6590815440010956193/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://ferozedaud.blogspot.com/2009/09/implementing-traceroute-with-systemnet_07.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/6590815440010956193?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/6590815440010956193?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/FerozesMusingsOnTechnology/~3/hYoeEqFVEp8/implementing-traceroute-with-systemnet_07.html" title="Implementing Traceroute with System.Net: Part-II" /><author><name>Feroze Daud</name><uri>https://profiles.google.com/106931323736171420480</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-htqG4D1zj34/AAAAAAAAAAI/AAAAAAAAAJM/o1zOCSZPA3c/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://ferozedaud.blogspot.com/2009/09/implementing-traceroute-with-systemnet_07.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0AFSXwzeyp7ImA9WxNREU8.&quot;"><id>tag:blogger.com,1999:blog-6013019333081665053.post-8526168154893328522</id><published>2009-09-04T20:17:00.000-07:00</published><updated>2009-09-04T20:35:18.283-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-04T20:35:18.283-07:00</app:edited><title>Implementing traceroute with System.Net: Part-I</title><content type="html">In the last part, I started by giving links to my implementation of the Ping utility, that used System.Net.Sockets.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ferozedaud.blogspot.com/2009/08/implementing-traceroute-with-systemnet.html"&gt;http://ferozedaud.blogspot.com/2009/08/implementing-traceroute-with-systemnet.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In this part, we will talk about traceroute. Traceroute is a general purpose utility that is used to discover a network path from the source to the destination. Traceroute is similar to Ping, in that it uses the ICMP protocol to send ICMP Echo request packets to the server. However, one key difference, is that it additionally uses the IP &lt;a href="http://en.wikipedia.org/wiki/Time_to_live"&gt;Time To Live&lt;/a&gt; (TTL) mechanism to specify the lifetime of the outgoing packets.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;When the TTL expires on a packet, the receiving host must send an ICMP "&lt;a href="http://en.wikipedia.org/wiki/ICMP_Time_Exceeded"&gt;Time Exceeded&lt;/a&gt;" message to the sender. The sender looks at this packet, and gets the IPAddress/HostName of the host that responded.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So, the basic algorithm for this goes as follows:&lt;br /&gt;&lt;br /&gt;while (reply.address != dest.address)&lt;br /&gt;  int ttl = 1;&lt;br /&gt;  for i = 1 to 3&lt;br /&gt;  send a packet to the host at address dest.address with TTL=ttl&lt;br /&gt;  wait for reply&lt;br /&gt;  if (timeout) then&lt;br /&gt;    print "*"&lt;br /&gt;  else&lt;br /&gt;    print ipaddress of host thatresponded&lt;br /&gt;  // increase the TTL&lt;br /&gt;  ttl = ttl + 1;&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;This should be pretty easy to implement, given that we have already implemented a PING client in previous episodes, that does all the heavy lifting for us, in terms of marshalling the ICMP packet from managed code to network byte order, etc.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blogs.msdn.com/feroze_daud/archive/2005/10/20/483088.aspx"&gt;http://blogs.msdn.com/feroze_daud/archive/2005/10/20/483088.aspx&lt;/a&gt;&lt;br /&gt;&lt;a href="http://blogs.msdn.com/feroze_daud/archive/2005/10/23/483976.aspx"&gt;http://blogs.msdn.com/feroze_daud/archive/2005/10/23/483976.aspx&lt;/a&gt;&lt;br /&gt;&lt;a href="http://blogs.msdn.com/feroze_daud/archive/2005/10/24/484260.aspx"&gt;http://blogs.msdn.com/feroze_daud/archive/2005/10/24/484260.aspx&lt;/a&gt;&lt;br /&gt;&lt;a href="http://blogs.msdn.com/feroze_daud/archive/2005/10/26/485372.aspx"&gt;http://blogs.msdn.com/feroze_daud/archive/2005/10/26/485372.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In the next part, we will modify the Ping utility to convert it into a Traceroute implementation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6013019333081665053-8526168154893328522?l=ferozedaud.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/gMK7c3F9QVDDBcHqKuJaJvHRkKo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gMK7c3F9QVDDBcHqKuJaJvHRkKo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/gMK7c3F9QVDDBcHqKuJaJvHRkKo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gMK7c3F9QVDDBcHqKuJaJvHRkKo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FerozesMusingsOnTechnology/~4/yBhdHHU8qRA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ferozedaud.blogspot.com/feeds/8526168154893328522/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://ferozedaud.blogspot.com/2009/09/implementing-traceroute-with-systemnet.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/8526168154893328522?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/8526168154893328522?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/FerozesMusingsOnTechnology/~3/yBhdHHU8qRA/implementing-traceroute-with-systemnet.html" title="Implementing traceroute with System.Net: Part-I" /><author><name>Feroze Daud</name><uri>https://profiles.google.com/106931323736171420480</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-htqG4D1zj34/AAAAAAAAAAI/AAAAAAAAAJM/o1zOCSZPA3c/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://ferozedaud.blogspot.com/2009/09/implementing-traceroute-with-systemnet.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkIEQnk8fyp7ImA9WxNXEks.&quot;"><id>tag:blogger.com,1999:blog-6013019333081665053.post-8164275851799374406</id><published>2009-08-27T09:56:00.000-07:00</published><updated>2009-09-29T16:55:03.777-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-29T16:55:03.777-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Tracing" /><category scheme="http://www.blogger.com/atom/ns#" term="System.Net" /><category scheme="http://www.blogger.com/atom/ns#" term="Microsoft" /><title>Tracing with System.Net</title><content type="html">In my old &lt;a href="http://blogs.msdn.com/feroze_daud/archive/2005/05/12/416922.aspx"&gt;blog&lt;/a&gt;, I had written a config file that shows how to enable trace logging for System.Net. Since it is useful, here is the config file again..&lt;br /&gt;
&lt;br /&gt;
&lt;pre name="code" class="xml"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8" ?&amp;gt;

    &amp;lt;configuration&amp;gt;
    &amp;lt;system.diagnostics&amp;gt;
    &amp;lt;trace autoflush="true" /&amp;gt;

    &amp;lt;sources&amp;gt;
    &amp;lt;source name="System.Net"&amp;gt;

    &amp;lt;listeners&amp;gt;
        &amp;lt;add name="System.Net"/&amp;gt;
    &amp;lt;/listeners&amp;gt;
    &amp;lt;/source&amp;gt;
    &amp;lt;source name="System.Net.Sockets"&amp;gt;
    &amp;lt;listeners&amp;gt;
        &amp;lt;add name="System.Net"/&amp;gt;
    &amp;lt;/listeners&amp;gt;
    &amp;lt;/source&amp;gt;
    &amp;lt;source name="System.Net.Cache"&amp;gt;
    &amp;lt;listeners&amp;gt;
        &amp;lt;add name="System.Net"/&amp;gt;
    &amp;lt;/listeners&amp;gt;
    &amp;lt;/source&amp;gt;
    &amp;lt;/sources&amp;gt;
    &amp;lt;sharedListeners&amp;gt;
        &amp;lt;add
            name="System.Net"
            type="System.Diagnostics.TextWriterTraceListener"
            initializeData="System.Net.trace.log"
        /&amp;gt;
    &amp;lt;/sharedListeners&amp;gt;
    &amp;lt;switches&amp;gt;
        &amp;lt;add name="System.Net" value="Verbose" /&amp;gt;
        &amp;lt;add name="System.Net.Sockets" value="Verbose" /&amp;gt;               
        &amp;lt;add name="System.Net.Cache" value="Verbose" /&amp;gt;
    &amp;lt;/switches&amp;gt;
&amp;lt;/system.diagnostics&amp;gt;
&amp;lt;/configuration&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
NOTE: If you are doing logging inside of the ASP.NET process, make sure to give the ASP.NET process identity WRITE permissions to the directory where you want the log to be written.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6013019333081665053-8164275851799374406?l=ferozedaud.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/q_PLl8JI3y1MFeQhoBmBmwXhieI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/q_PLl8JI3y1MFeQhoBmBmwXhieI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/q_PLl8JI3y1MFeQhoBmBmwXhieI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/q_PLl8JI3y1MFeQhoBmBmwXhieI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FerozesMusingsOnTechnology/~4/UVttMYy8K64" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ferozedaud.blogspot.com/feeds/8164275851799374406/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://ferozedaud.blogspot.com/2009/08/tracing-with-systemnet.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/8164275851799374406?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/8164275851799374406?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/FerozesMusingsOnTechnology/~3/UVttMYy8K64/tracing-with-systemnet.html" title="Tracing with System.Net" /><author><name>Feroze Daud</name><uri>https://profiles.google.com/106931323736171420480</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-htqG4D1zj34/AAAAAAAAAAI/AAAAAAAAAJM/o1zOCSZPA3c/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://ferozedaud.blogspot.com/2009/08/tracing-with-systemnet.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0EHSHg9eip7ImA9WxNSGEk.&quot;"><id>tag:blogger.com,1999:blog-6013019333081665053.post-7690055563514280878</id><published>2009-08-23T14:16:00.001-07:00</published><updated>2009-09-01T15:53:59.662-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-01T15:53:59.662-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Exchange" /><category scheme="http://www.blogger.com/atom/ns#" term="Microsoft" /><category scheme="http://www.blogger.com/atom/ns#" term="Unified Messaging" /><title>Things I did at Microsoft: Outbound Dialing Rules for Exchange Unified Messaging</title><content type="html">Continuing my series on things that I did at Microsoft: in this part, I talk about outbound dialing rules that I implemented for Exchange Server 2007.&lt;br /&gt;&lt;br /&gt;Exchange Unified Messaging server provides the functionality to place outbound calls. For eg, imagine a customer calling the corporate switchboard, and looking up the person he wants to talk to, using the AutoAttendant. Imagine that the target person is not in the US, and in order to call him, a long distance call will need to be placed.&lt;br /&gt;&lt;br /&gt;It is possible that the company might want to prevent that call and instead route the caller to an operator. This is implemented by the concept of dialing rules.&lt;br /&gt;&lt;br /&gt;The UM administrator can configure dialing rules on the AutoAttendant, DialPlan or Mailbox Policy. When the UM server needs to place an outbound call, it consults the dialing rules, and figures out whether the call is allowed. It also figures out the effective number to be called - this number will have the correct outside line access code (for eg: prepending the target number with a '9' to signify to the PBX that the numbe is an external number).&lt;br /&gt;&lt;br /&gt;More details about this feature can be found in this article: &lt;a href="http://msexchangeteam.com/archive/2007/01/29/432440.aspx"&gt;http://msexchangeteam.com/archive/2007/01/29/432440.aspx&lt;/a&gt; which discusses how to create dialing rules.&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&amp;bc1=000000&amp;IS2=1&amp;npa=1&amp;bg1=FFFFFF&amp;fc1=000000&amp;lc1=0000FF&amp;t=ferozesmusing-20&amp;o=1&amp;p=8&amp;l=as1&amp;m=amazon&amp;f=ifr&amp;asins=B000JIOJWI" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6013019333081665053-7690055563514280878?l=ferozedaud.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/CGvXjfc1kVZUW2TRTBXh9baRLsk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CGvXjfc1kVZUW2TRTBXh9baRLsk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/CGvXjfc1kVZUW2TRTBXh9baRLsk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CGvXjfc1kVZUW2TRTBXh9baRLsk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FerozesMusingsOnTechnology/~4/T1jUcB0mCsU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ferozedaud.blogspot.com/feeds/7690055563514280878/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://ferozedaud.blogspot.com/2009/08/things-i-did-at-microsoft-outbound.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/7690055563514280878?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/7690055563514280878?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/FerozesMusingsOnTechnology/~3/T1jUcB0mCsU/things-i-did-at-microsoft-outbound.html" title="Things I did at Microsoft: Outbound Dialing Rules for Exchange Unified Messaging" /><author><name>Feroze Daud</name><uri>https://profiles.google.com/106931323736171420480</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-htqG4D1zj34/AAAAAAAAAAI/AAAAAAAAAJM/o1zOCSZPA3c/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://ferozedaud.blogspot.com/2009/08/things-i-did-at-microsoft-outbound.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0EBR3c_fyp7ImA9WxNSGEk.&quot;"><id>tag:blogger.com,1999:blog-6013019333081665053.post-3186836520661620356</id><published>2009-08-23T14:06:00.000-07:00</published><updated>2009-09-01T15:54:16.947-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-01T15:54:16.947-07:00</app:edited><title>Implementing Traceroute with System.Net - Introduction</title><content type="html">Previously, I have shown how you can implement a Ping utility using System.Net.Sockets.&lt;br /&gt;&lt;br /&gt;The following are the links to the four part article that describe the implementation.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blogs.msdn.com/feroze_daud/archive/2005/10/20/483088.aspx"&gt;http://blogs.msdn.com/feroze_daud/archive/2005/10/20/483088.aspx&lt;/a&gt;&lt;br /&gt;&lt;a href="http://blogs.msdn.com/feroze_daud/archive/2005/10/23/483976.aspx"&gt;http://blogs.msdn.com/feroze_daud/archive/2005/10/23/483976.aspx&lt;/a&gt;&lt;br /&gt;&lt;a href="http://blogs.msdn.com/feroze_daud/archive/2005/10/24/484260.aspx"&gt;http://blogs.msdn.com/feroze_daud/archive/2005/10/24/484260.aspx&lt;/a&gt;&lt;br /&gt;&lt;a href="http://blogs.msdn.com/feroze_daud/archive/2005/10/26/485372.aspx"&gt;http://blogs.msdn.com/feroze_daud/archive/2005/10/26/485372.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Ping is used to figure out if a destination host is responding on the network.&lt;br /&gt;&lt;br /&gt;With a few modifications, we can change ping so that it shows us the routes that a packet is taking through the network.&lt;br /&gt;&lt;br /&gt;In the next part, we will look at traceroute, and see how we can use the principles in writing our own traceroute utility from scratch.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6013019333081665053-3186836520661620356?l=ferozedaud.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/HhFUP08N9Ce8YxSMJo19fhAIgWY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HhFUP08N9Ce8YxSMJo19fhAIgWY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/HhFUP08N9Ce8YxSMJo19fhAIgWY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HhFUP08N9Ce8YxSMJo19fhAIgWY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FerozesMusingsOnTechnology/~4/xAFyjTkABas" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ferozedaud.blogspot.com/feeds/3186836520661620356/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://ferozedaud.blogspot.com/2009/08/implementing-traceroute-with-systemnet.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/3186836520661620356?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/3186836520661620356?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/FerozesMusingsOnTechnology/~3/xAFyjTkABas/implementing-traceroute-with-systemnet.html" title="Implementing Traceroute with System.Net - Introduction" /><author><name>Feroze Daud</name><uri>https://profiles.google.com/106931323736171420480</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-htqG4D1zj34/AAAAAAAAAAI/AAAAAAAAAJM/o1zOCSZPA3c/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://ferozedaud.blogspot.com/2009/08/implementing-traceroute-with-systemnet.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0EDRnozeip7ImA9WxNSGEk.&quot;"><id>tag:blogger.com,1999:blog-6013019333081665053.post-4071334705278191057</id><published>2009-08-17T09:52:00.000-07:00</published><updated>2009-09-01T15:54:37.482-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-01T15:54:37.482-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Miscellaneous" /><title>Dell refutes Microsoft's Netbook return claims</title><content type="html">At the open source world conference, Dell's Senior Product Manager, Todd Finch refuted microsoft's claim that return rates for Linux netbooks have been much higher than windows netbooks.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.crn.com/hardware/219300174;jsessionid=ULPLFEHHWWCLDQE1GHRSKH4ATMY32JVN"&gt;http://www.crn.com/hardware/219300174;jsessionid=ULPLFEHHWWC&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Originally, I thought that the return rate made sense, because people buying cheap netbooks would find the task of learning Linux/Ubuntu UI a huge task. But it appears that the people buying these netbooks are computer savvy, if Dells experience is to be believed.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;However, to get a fuller picture, we also need the story across all hardware vendors that are selling netbooks.&lt;/div&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;&lt;iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&amp;bc1=000000&amp;IS2=1&amp;bg1=FFFFFF&amp;fc1=000000&amp;lc1=0000FF&amp;t=ferozesmusing-20&amp;o=1&amp;p=8&amp;l=as1&amp;m=amazon&amp;f=ifr&amp;asins=B002DYIXMS" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6013019333081665053-4071334705278191057?l=ferozedaud.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/3cCZ4NXuIwPX4RagD2a_7mSmCcY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/3cCZ4NXuIwPX4RagD2a_7mSmCcY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/3cCZ4NXuIwPX4RagD2a_7mSmCcY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/3cCZ4NXuIwPX4RagD2a_7mSmCcY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FerozesMusingsOnTechnology/~4/CTV7ZWY8rX0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ferozedaud.blogspot.com/feeds/4071334705278191057/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://ferozedaud.blogspot.com/2009/08/dell-refutes-microsofts-netbook-return.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/4071334705278191057?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/4071334705278191057?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/FerozesMusingsOnTechnology/~3/CTV7ZWY8rX0/dell-refutes-microsofts-netbook-return.html" title="Dell refutes Microsoft's Netbook return claims" /><author><name>Feroze Daud</name><uri>https://profiles.google.com/106931323736171420480</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-htqG4D1zj34/AAAAAAAAAAI/AAAAAAAAAJM/o1zOCSZPA3c/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://ferozedaud.blogspot.com/2009/08/dell-refutes-microsofts-netbook-return.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0AER386eSp7ImA9WxNSGEk.&quot;"><id>tag:blogger.com,1999:blog-6013019333081665053.post-2877019154613303336</id><published>2009-08-13T19:14:00.001-07:00</published><updated>2009-09-01T15:55:06.111-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-01T15:55:06.111-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Exchange" /><category scheme="http://www.blogger.com/atom/ns#" term="Microsoft" /><category scheme="http://www.blogger.com/atom/ns#" term="Unified Messaging" /><title>Things I did at Microsoft - Call Answering Rules</title><content type="html">&lt;a href="http://blogs.msdn.com/larryosterman"&gt;Larry Osterman&lt;/a&gt; started a series of posts on his blog, where he talks about the stuff he was doing in the past. So, I thought it would be a good idea to talk about suff I did at Microsoft.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One of the things that I am really proud about, is a feature I implemented for Exchange2009, which is called "Call Answering Rules". The best way to explain this, is to think about it as the equivalent of the Exchange/Outlook rules, but for your phone. This allows you to create rules that govern how incoming calls to your phone are routed. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Some of the examples of rules you can create are:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;1) Forward all calls with a given caller-id to my cell phone.&lt;/div&gt;&lt;div&gt;2) If my client calls and I am in a meeting, forward to voicemail.&lt;/div&gt;&lt;div&gt;3) If a call comes, and my Free-Busy status says "Out of office", then call two other numbers configured by me.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I implemented the rules engine for this feature. You can get more details about the feature from this blog &lt;a href="http://msexchangeteam.com/archive/2009/06/22/451667.aspx"&gt;http://msexchangeteam.com/archive/2009/06/22/451667.aspx&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6013019333081665053-2877019154613303336?l=ferozedaud.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/KjAPMHnOxNPAYii0pbvX8HhdWvk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/KjAPMHnOxNPAYii0pbvX8HhdWvk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/KjAPMHnOxNPAYii0pbvX8HhdWvk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/KjAPMHnOxNPAYii0pbvX8HhdWvk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FerozesMusingsOnTechnology/~4/i_NjajdrgU8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ferozedaud.blogspot.com/feeds/2877019154613303336/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://ferozedaud.blogspot.com/2009/08/things-i-did-at-microsoft-call.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/2877019154613303336?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/2877019154613303336?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/FerozesMusingsOnTechnology/~3/i_NjajdrgU8/things-i-did-at-microsoft-call.html" title="Things I did at Microsoft - Call Answering Rules" /><author><name>Feroze Daud</name><uri>https://profiles.google.com/106931323736171420480</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-htqG4D1zj34/AAAAAAAAAAI/AAAAAAAAAJM/o1zOCSZPA3c/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://ferozedaud.blogspot.com/2009/08/things-i-did-at-microsoft-call.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUMCQ3syeSp7ImA9WxNSFkQ.&quot;"><id>tag:blogger.com,1999:blog-6013019333081665053.post-6314098192802164249</id><published>2009-08-13T18:36:00.000-07:00</published><updated>2009-08-30T21:37:42.591-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-30T21:37:42.591-07:00</app:edited><title>Hi!</title><content type="html">Welcome to my blog. Here, I will post my thoughts on Software, as well as code snippets and other stuff.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For my previous blog, you can see &lt;a href="http://blogs.msdn.com/feroze_daud"&gt;http://blogs.msdn.com/feroze_daud&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6013019333081665053-6314098192802164249?l=ferozedaud.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/0ictSBgiXIIVapbSPgSAxop1eBc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0ictSBgiXIIVapbSPgSAxop1eBc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/0ictSBgiXIIVapbSPgSAxop1eBc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0ictSBgiXIIVapbSPgSAxop1eBc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/FerozesMusingsOnTechnology/~4/nXphreNXJpI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://ferozedaud.blogspot.com/feeds/6314098192802164249/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://ferozedaud.blogspot.com/2009/08/hi.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/6314098192802164249?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6013019333081665053/posts/default/6314098192802164249?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/FerozesMusingsOnTechnology/~3/nXphreNXJpI/hi.html" title="Hi!" /><author><name>Feroze Daud</name><uri>https://profiles.google.com/106931323736171420480</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-htqG4D1zj34/AAAAAAAAAAI/AAAAAAAAAJM/o1zOCSZPA3c/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://ferozedaud.blogspot.com/2009/08/hi.html</feedburner:origLink></entry></feed>

