Whois گرفتن (جستجوی نام های دامنه) در C# ASP.NET

برای انجام عمل جستجو ابتدا باید یک ارتباط با سرورهایی که بانکهای اطلاعاتی آنها این مشخصات را دارند ارتباط برقرار کرد و با یک Query، اطلاعات مورد نظر را درخواست نمود. این ارتباط از نوع TCP و از طریق پورت 43 انجام می گیرد. لیست کاملی از این سرورها را اینجا می توانید ببینید.

مشخص کردن فضا نامها
ابتدا فضا نامهای مورد نیاز را مشخص می کنیم:

Using System.Net.Sockets;
Using System.Text;
Using System.IO
Using System.Text.RegularExpressions;

با استفاده از TcpClient در NetFramework. می توانیم این ارتباط را با سرور مورد نظر برقرار نماییم. برای استفاده از این کلاس باید فضانام System.Net.Sockets را وارد کنیم. از دو فضانام دیگر نیز برای فرمت ورودی و خروجی خود استفاده می کنیم.

ایجاد و ارسال Query
ابتدا متغیرهای مورد نیاز را تعریف می کنیم:

string StrSvr,StrDomain, Resp;
TcpClient TcpClt;
byte[] ArrDomain;
Stream TcpStr;
StreamReader TcpStrRdr;

حال باید رشته ای را که می خواهیم به عنوان Query به سرور ارسال نماییم، ایجاد کنیم. برای این کار باید نام درخواستی کاربر را همراه پسوند مورد نظر(Com ،Org،...) را به سرور ارسال نماییم. توجه داشته باشید که هر کدام از سرورهای موجود در لیست فوق الذکر برای جستجوی پسوند خاصی می باشد. برای مثال whois.internic.com تنها برای دامنه های net. و com. و edu. می باشد و اگر دامنه ای با پسوند Info. را با این سرور جستجو نمایید، جواب مطلوب را نخواهید گرفت.

بنابراین ابتدا باید پسوند مورد نظر کاربر و سپس سرور مربوطه را مشخص نماییم . در اینجا برای انتخاب پسوند از DropDownList استفاده کرده ام:

if (DDLstSuffix.SelectedItem.Value == ".COM" || DDLstSuffix.SelectedItem.Value == ".NET" || DDLstSuffix.SelectedItem.Value == ".EDU")
{
    StrSvr = "whois.internic.net";
    StrDomain = TxtDomainName.Text.Trim() + DDLstSuffix.SelectedItem.Value+ "\r\n";
}
else if (DDLstSuffix.SelectedItem.Value == ".ORG")
{
    StrSvr = "whois.publicinterestregistry.net";
    StrDomain = TxtDomainName.Text.Trim() + DDLstSuffix.SelectedItem.Value+ "\r\n";
}
else if (DDLstSuffix.SelectedItem.Value == ".BIZ")
{
    StrSvr = "whois.neulevel.biz";
    StrDomain = TxtDomainName.Text.Trim() + DDLstSuffix.SelectedItem.Value+ "\r\n";
}
else if (DDLstSuffix.SelectedItem.Value == ".INFO")
{
    StrSvr = "whois.afilias.info";
    StrDomain = TxtDomainName.Text.Trim() + DDLstSuffix.SelectedItem.Value+ "\r\n";
}
else if ((DDLstSuffix.SelectedItem.Value == ".IR") || (DDLstSuffix.SelectedItem.Value == ".CO.IR") || (DDLstSuffix.SelectedItem.Value == ".NET.IR") || (DDLstSuffix.SelectedItem.Value == "ID.IR"))
{
    StrSvr = "whois.nic.ir";
    StrDomain = TxtDomainName.Text.Trim() + DDLstSuffix.SelectedItem.Value+ "\r\n";
}

همانطور که می بینید، رشته ای که برای جستجو ارسال می شود به "r\n\" ختم می شود. اگر این رشته را در انتهای نام دامنه قرار ندهید، سرور نمی تواند جواب مطلوب را برگرداند.

اتصال به سرور
حال یک ارتباط باید با سرور مورد نظر برقرار نماییم. کلاس TcpClient، متدهایی برای اتصال، دریافت و ارسال اطلاعات دارد. به دو صورت می توانیم با یک سرور ارتباط برقرار کنیم:

1 – ایجاد یک نمونه از کلاس TcpClient بدون هیچ پارامتری و سپس استفاده از متد Connect:

TcpClient TcpClt = new TcpClient();
TcpClt.Connect(StrSvr,43);

2 – ایجاد یک نمونه از کلاس TcpClient با پارامترهای آدرس سرور و پورت مقصد که می خواهید با آن ارتباط برقرار کنید. این Constructor ارتباط را به صورت اتوماتیک ایجاد می کند:

TcpClient objTCPC = new TcpClient(StrSvr, 43);

پس از آن با متد GetBytes کلاس Encoding (فضا نام System.Text) رشته StrDomain را به یک آرایه از نوع بایت می نویسیم.

ArrDomain = Encoding.ASCII.GetBytes(strDomain);

با استفاده از متد GetStream کلاس TcpClient ، یک Stream ایجاد می کنیم و از طریق آن به ارسال و دریافت اطلاعات می پردازیم:

TcpStr = TcpClt.GetStream();

با استفاده از این Stream می توانیم با متد Write یک آرایه از Byte را در Stream جاری نوشت :

TcpStr.Write (ArrDomain,0,StrDomain.Length);

دریافت و نمایش نتیجه جستجو
یکی از راههای دریافت اطلاعات از سرور، ایجاد یک نمونه از کلاس StreamReader و سپس خواندن اطلاعات بر اساس یک Encoding مشخص می باشد.


TcpStrRdr = new StreamReader(TcpClt.GetStream(),Encoding.ASCII);

قدم بعد، استفاده از متد ReadToEnd برای دریافت جواب سرور می باشد. این رشته شامل کاراکترهای خط جدید "n\" می باشد که باید با "<br>" جایگزین شود. برای این کار از متد Replace کلاس RegEx استفاده می کنیم ، سپس برای راحتی جستجو این رشته را به حروف کوچک تبدیل می کنیم :

Resp = Regex.Replace(TcpStrRdr.ReadToEnd(),"\n","<br>");
Resp = Resp.ToLower();

اگر در این رشته، زیر رشته هایی مانند "no match" یا "not found" یا "no entries found" وجود داشته باشد، نام دامنه مورد نظر آزاد می باشد. در غیر اینصورت آن دامنه ثبت شده است. حال با استفاده از این مساله، نتیجه را به کاربر اعلام می کنیم. برای جستجوی این زیر رشته ها از متد IsMatch کلاس RegEx استفاده می کنیم. اگر در این متد زیر رشته مورد نظر در رشته موجود باشد True و در غیر اینصورت False برگشت داده می شود.

if (Regex.IsMatch(Resp,"no match") || Regex.IsMatch(Resp,"not found") || Regex.IsMatch(Resp,"no entries found"))
{

    SearchRes = " دامنه مورد نظر موجود می باشد ";

    PnlOrder.Visible = true;
    PnlOrderOk.Visible = false;
}
else
{

    SearchRes = " دامنه مورد نظر موجود نمی باشد ";

    PnlOrder.Visible = false;
    PnlOrderOk.Visible = false;
}

در انتها نیز ارتباط را می بندیم.

TcpClt.Close();