<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>.Net Adventures</title>
        <link>http://blogs.ugidotnet.org/tekanet/Default.aspx</link>
        <description>Appunti di viaggio dall'universo .Net</description>
        <language>it-IT</language>
        <copyright>Matteo Bagattini</copyright>
        <generator>Subtext Version 2.6.0.0</generator>
        <image>
            <title>.Net Adventures</title>
            <url>http://blogs.ugidotnet.org/images/RSS2Image.gif</url>
            <link>http://blogs.ugidotnet.org/tekanet/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <item>
            <title>Interrogare server Whois con .Net</title>
            <category>.Net softcore</category>
            <link>http://blogs.ugidotnet.org/tekanet/archive/2005/06/16/19352.aspx</link>
            <description>Come spesso accade, ci si ritrova a risolvere, grazie al Framework, problemi apparentemente intricati con poche righe di codice.&lt;br&gt;
E' il caso della classe che vi propongo, che esegue un'interrogazione ad un server Whois, ricevendo in cambio il record corrispondente (o un segnale di "not found") al dominio richiesto.

Innanzitutto i namespace da importare, che sono:
&lt;code&gt;
Imports System.Net&lt;br&gt;
Imports System.Net.Sockets&lt;br&gt;
Imports System.Text&lt;br&gt;
Imports System.IO
&lt;/code&gt;

La logica dietro a questa classe sarà quella di inzialmente impostare tramite delle property R/W il server Whois da interrogare, il dominio da verificare e l'eventuale porta TCP (di fatto è sempre la 43 per i Whois). 

&lt;code&gt;
Private m_WhoisServer As String = String.Empty&lt;br&gt;
Private m_Port As Integer = 43&lt;br&gt;
Private m_Domain As String = String.Empty&lt;br&gt;
&lt;br&gt;
Public Property Domain() As String&lt;br&gt;
    Get&lt;br&gt;
        Return m_Domain&lt;br&gt;
    End Get&lt;br&gt;
    Set(ByVal Value As String)&lt;br&gt;
        m_Domain = Value + vbCrLf&lt;br&gt;
    End Set&lt;br&gt;
End Property&lt;br&gt;
&lt;br&gt;
Public Property Port() As Integer&lt;br&gt;
    Get&lt;br&gt;
        Return m_Port&lt;br&gt;
    End Get&lt;br&gt;
    Set(ByVal Value As Integer)&lt;br&gt;
        m_Port = Value&lt;br&gt;
    End Set&lt;br&gt;
End Property&lt;br&gt;
&lt;br&gt;
Public Property WhoisServer() As String&lt;br&gt;
    Get&lt;br&gt;
        Return m_WhoisServer&lt;br&gt;
    End Get&lt;br&gt;
    Set(ByVal Value As String)&lt;br&gt;
        m_WhoisServer = Value&lt;br&gt;
    End Set&lt;br&gt;
End Property&lt;br&gt;
&lt;/code&gt;

Per comodità, un overload del costruttore accetta direttamente server e dominio da verificare:

&lt;code&gt;
Public Sub New()&lt;br&gt;
    '&lt;br&gt;
End Sub&lt;br&gt;
&lt;br&gt;
Public Sub New(ByVal WhoisServer As String, ByVal Domain As String)&lt;br&gt;
    Me.WhoisServer = WhoisServer&lt;br&gt;
    Me.Domain = Domain&lt;br&gt;
End Sub&lt;br&gt;
&lt;/code&gt;

Infine il codice principale, che esegue la query. Utilizzo un oggetto TcpClient, lo connetto al server e alla porta richiesto e imposto un timeout accettabile. Quindi passo, codificato in ASCII.GetBytes, il dominio da verificare. Da notare che quando viene impostata la property Domain, aggiungo alla fine il carattere di ritorno a capo: non settando questa chiusura, la richiesta al server rimane "appesa" (si può verificare la query anche tramite Telnet). Infine, leggo in uno streamreader il risultato restituito dal server.

&lt;code&gt;
Public Function Query() As String&lt;br&gt;
&lt;br&gt;
	Dim TCPC As New TcpClient&lt;br&gt;
	Dim sReturn As String&lt;br&gt;
	&lt;br&gt;
	Try&lt;br&gt;
	    TCPC.Connect(Me.WhoisServer, Me.Port)&lt;br&gt;
	    TCPC.ReceiveTimeout = 5000&lt;br&gt;
	    Dim arrDomain As Byte() = Encoding.ASCII.GetBytes(Me.Domain.ToCharArray)&lt;br&gt;
	    Dim s As Stream = TCPC.GetStream&lt;br&gt;
	    s.Write(arrDomain, 0, Me.Domain.Length)&lt;br&gt;
	    Dim sr As New StreamReader(TCPC.GetStream(), Encoding.ASCII)&lt;br&gt;
	&lt;br&gt;
	    sReturn = sr.ReadToEnd&lt;br&gt;
	&lt;br&gt;
	    TCPC.Close()&lt;br&gt;
	Catch e As Exception&lt;br&gt;
	    sReturn = "Errore di comunicazione con il server " + Me.WhoisServer&lt;br&gt;
	End Try&lt;br&gt;
	&lt;br&gt;
	Return sReturn&lt;br&gt;
&lt;br&gt;
End Function&lt;br&gt;
&lt;/code&gt;

Ho utilizzato un blocco try-catch anche se preferisco sempre farne a meno, poichè ho sviluppato la classe in fretta e non ho potuto analizzare attentamente la gestione degli errori derivanti dall'oggetto TcpClient. Se qualcuno ha soluzioni più eleganti, sono sempre ben accette!

That's all folks :)

tK&lt;img src="http://blogs.ugidotnet.org/tekanet/aggbug/19352.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Matteo Bagattini</dc:creator>
            <guid>http://blogs.ugidotnet.org/tekanet/archive/2005/06/16/19352.aspx</guid>
            <pubDate>Thu, 16 Jun 2005 10:32:00 GMT</pubDate>
            <comments>http://blogs.ugidotnet.org/tekanet/archive/2005/06/16/19352.aspx#feedback</comments>
            <slash:comments>9</slash:comments>
            <wfw:commentRss>http://blogs.ugidotnet.org/tekanet/comments/commentRss/19352.aspx</wfw:commentRss>
            <trackback:ping>http://blogs.ugidotnet.org/tekanet/services/trackbacks/19352.aspx</trackback:ping>
        </item>
    </channel>
</rss>