I'd like to write a fairly simple client-server network app. I only use a pure IPv4 network, but it would be nice to future-proof my code. I'll probably be using TcpListener/TcpClient, because preliminary investigation of WCF reveals it to be overly complex to set up and hard to grok.
For the client side, does .NET provide a facility to automatically decode a string that contains an IPv4 or IPv6 address (where the IPv4 address includes a port number)? Bonus points if it can resolve a domain name.
For the server side, I heard IPv6 doesn't use port numbers, so what's the equivalent of the port to listen on, and is there a standard way to differentiate a IPv4 port number string from the IPv6 equivalent? Never mind, IPv6 services have 16-bit port numbers just like IPv4 ones.
Yep System.Net.IPAddress
IPAddress.Parse( "fe80::21c:42ff:fe00:8%vnic0" );
IPAddress.Parse( "127.0.0.1" );
And to test for IPv4 or v6
if( IPAddress.Parse(...).AddressFamily == AddressFamily.InterNetwork )
// IPv4 address
System.Net.IPAddress can be used to parse strings representing valid IPv4 and IPv6 addresses. System.Net.Dns can be used to resolve hostnames and addresses on a network.
For both,
using System.Net;
@Qwertie said:
Since IPv6 addresses also contain colons, I wonder what the proper way is to decode a IPv6 address or IPv4 address that contains a port number.
As others have noted, a port number is not part of an IP address (either IPv4 or IPv6). IP addresses are atomic, unsigned integers (IPv4 is 32-bit, IPv6 is 128-bit). When represented in character form (such as a URI), they may be combined with a port number (and other information). Within a URI, the host and port are [can be] a part of the authority portion of a URI.
URIs may be parsed into their constituent parts using System.Uri
. The Authority
portion of a URI is composed of the following properties: Host
, Port
(and, optionally, and deprecated, the UserInfo subcomponent, consisting of username and password). The property HostNameType
will tell you what kind of hostname you've got, a value of the enum UriHostNameType
: Dns, Ipv4, Ipv6 or something else.
You can also parse a URI into its component parts using the regular expression defined in Appendix B of RFC 3986:
Appendix B. Parsing a URI Reference with a Regular Expression
As the "first-match-wins" algorithm is identical to the "greedy" disambiguation method used by POSIX regular expressions, it is natural and commonplace to use a regular expression for parsing the potential five components of a URI reference.
The following line is the regular expression for breaking-down a well-formed URI reference into its components.
^(([^:/?#]+):)?(//([^/?#]))?([^?#])(\?([^#]))?(#(.))? 12 3 4 5 6 7 8 9
The numbers in the second line above are only to assist readability; they indicate the reference points for each subexpression (i.e., each paired parenthesis). We refer to the value matched for subexpression <n> as $<n>. For example, matching the above expression to
http://www.ics.uci.edu/pub/ietf/uri/#Related
results in the following subexpression matches:
$1 = http: $2 = http $3 = //www.ics.uci.edu $4 = www.ics.uci.edu $5 = /pub/ietf/uri/ $6 = $7 = $8 = #Related $9 = Related
where <undefined> indicates that the component is not present, as is the case for the query component in the above example. Therefore, we can determine the value of the five components as
scheme = $2 authority = $4 path = $5 query = $7 fragment = $9
Going in the opposite direction, we can recreate a URI reference from its components by using the algorithm of Section 5.3.
Note though that this regular expression seems to be slightly incorrect. According to the errata for RFC 3986 and its antecedent, RFC 2396:
Errata ID: 1933
Status: Verified Type: Technical Reported By: Skip Geel Date Reported: 2009-10-25 Verifier Name: Peter Saint-Andre Date Verified: 2010-11-11
Section appendix B says:
^(([^:/?#]+):)?(//([^/?#]))?([^?#])(\?([^#]))?(#(.))?
It should say:
/^(([^:\/?#]+):)?(\/\/([^\/?#]))?([^?#])(\?([^#]))?(#(.))?/
Notes:
A Regular Expression is delimited by the slash ("/"). Within it a slash should be preceded by a back-slash ("\").
Peter: This also applies to RFC 3986.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With