PDA

View Full Version : socket programming_ ساخت DNS و بدست آوردن فرکانس مراجعه به هر سیستم



sh_m
پنج شنبه 18 خرداد 1391, 11:46 صبح
سلام خدمت همه دوستان
من می خوام یک DNS ساده بسازم . کدی نوشتم که میاد آدرس IP و نام کلیه سیستم های عضو یک workgroup را در یک listview نمایش می ده. سوال اینکه این لیست حتما باید در یک database ذخیره بشه یا نیازی نیست؟
ضمنا می خوام فرکانس تعداد مراجعه به هر سیستم را بدست بیارم. با استفاده از چه رویدادی می تونم این کارو انجام بدم و چطور؟

منتظر پاسخ شما دوستداران سوکت پروگرمینگ هستم. خیلی مهمه.

با تشکر

Saeed_m_Farid
پنج شنبه 18 خرداد 1391, 17:31 عصر
سوال اول که خودتون میگین نوشتینش، برای ذخیره حتماً نمیخواد تو database ذخیره کنید؛ چون همونطورکه میدونید جداول IP table موقتی هستن و شما هم بهتره در یک پریود زمانی اونها رو آپدیت کنید، یه Hashtable یا Dictionary تو حافظه می تونید بصورت static برای هاست هاتون تعریف کنید و هروقت لازم شد ازش استفاده کنید، خیلی هم خواستید بهینه بشه موقع خروج تو یه فایل Xml ذخیره کنیدش و موقع لود شدن برنامه محتویاتش رو واکشی کنید ...
سوال دومتون رو (با اینکه از دوستداران سوکت پروگرمینگ هستم) نفهمیدم! شما مگه رو هر سیستم برنامه دارین؟ چطوری میخواین همچین کاری بکنید؟ کدش رو نمیگم منظورم اینه که رویداد باید به یه برنامه برسه که هندل بشه دیگه! اگه شما روی تمام کلاینت ها برنامه دارید و مثلاً NET remoting. استفاده می کنید، با یه روال پیچیده میشه کلاینت ها رو invoke کرد؛ یعنی برحسب اینکه کدوم کلاینت به سرور شما دسترسی پیدا کرده، روال کاری اش رو لاگ کنید یا counter بذارید و ...

برای این کار باید از IServerChannelSinkProvider استفاده کنید و در هر کدوم از هاست هاتون این آیتم رو به برنامه کلاینت تون اضافه کنید:

using System;
using System.Collections;
using System.IO;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Channels;
using System.Threading;
using System.Net;

namespace MyRemotingEnvironment
{
public class ClientIPServerSinkProvider :
IServerChannelSinkProvider
{
private IServerChannelSinkProvider _nextProvider = null;

public ClientIPServerSinkProvider()
{
}

public ClientIPServerSinkProvider(
IDictionary properties,
ICollection providerData)
{
}

public IServerChannelSinkProvider Next
{
get { return _nextProvider; }
set { _nextProvider = value; }
}

public IServerChannelSink CreateSink(IChannelReceiver channel)
{
IServerChannelSink nextSink = null;

if (_nextProvider != null)
{
nextSink = _nextProvider.CreateSink(channel);
}
return new ClientIPServerSink(nextSink);
}

public void GetChannelData(IChannelDataStore channelData)
{
}
}



public class ClientIPServerSink :
BaseChannelObjectWithProperties,
IServerChannelSink,
IChannelSinkBase
{

private IServerChannelSink _nextSink;

public ClientIPServerSink(IServerChannelSink next)
{
_nextSink = next;
}

public IServerChannelSink NextChannelSink
{
get { return _nextSink; }
set { _nextSink = value; }
}

public void AsyncProcessResponse(
IServerResponseChannelSinkStack sinkStack,
Object state,
IMessage message,
ITransportHeaders headers,
Stream stream)
{
IPAddress ip = headers[CommonTransportKeys.IPAddress] as IPAddress;
CallContext.SetData("ClientIPAddress", ip);
sinkStack.AsyncProcessResponse(message, headers, stream);
}

public Stream GetResponseStream(
IServerResponseChannelSinkStack sinkStack,
Object state,
IMessage message,
ITransportHeaders headers)
{

return null;

}


public ServerProcessing ProcessMessage(
IServerChannelSinkStack sinkStack,
IMessage requestMsg,
ITransportHeaders requestHeaders,
Stream requestStream,
out IMessage responseMsg,
out ITransportHeaders responseHeaders,
out Stream responseStream)
{
if (_nextSink != null)
{
IPAddress ip =
requestHeaders[CommonTransportKeys.IPAddress] as IPAddress;
CallContext.SetData("ClientIPAddress", ip);
ServerProcessing spres = _nextSink.ProcessMessage(
sinkStack,
requestMsg,
requestHeaders,
requestStream,
out responseMsg,
out responseHeaders,
out responseStream);
return spres;
}
else
{
responseMsg = null;
responseHeaders = null;
responseStream = null;
return new ServerProcessing();
}
}


}
}


حالا می تونید در هاست موردنظرتون کاری مشابه این بکنید:
BinaryServerFormatterSinkProvider bp = new BinaryServerFormatterSinkProvider();
ClientIPServerSinkProvider csp = new ClientIPServerSinkProvider();
csp.Next = bp;
Hashtable ht = new Hashtable();
ht.Add("port", "8080"); // Your remoting port number
TcpChannel channel = new TcpChannel(ht, null, csp);
ChannelServices.RegisterChannel(channel, false);

RemotingConfiguration.RegisterWellKnownServiceType (
typeof(MyRemotedClass),
"MyRemotedClass.rem",
WellKnownObjectMode.SingleCall);


با این کار شما تونستید تو کامپیوترهای هاست، یه چیزی شبیه Callback درست کنید و تو سرور با فراخوانی این تابع، IP طرف رو بدست بیارید:
public class MyRemotedClass : MarshalByref
{
public void DoThis()
{
string clientIP = CallContext.GetData("ClientIPAddress").ToString();
}
}

ولی بازم فکر کنم با تلاش بسیار و مطالعه چندین باره سوال شما! بازم من از ته منظور شما رو تو سوال دوم درست متوجه نشدم و واسه خودم اراجیف بستم!

sh_m
جمعه 19 خرداد 1391, 19:59 عصر
سلام
با تشکر از پاسخ شما
خیلی به زحمت افتادین - شرمنده
این صورت یک پروژه درسیه. ولی من فکر می کنم منظور تعداد مراجعات از سرور به هر سیستم هست. نمی دونم منظور از این مراجعه چیه.سوال دقیقا اینه
"فرکانس استفاده از هر مراجعه به هر : ASCII name را شمارش کند"
شما برداشتتون چیه ؟
یک سوال دیگه - چطور میشه کاری کرد که DNS ی که دارم علاوه بر workgroup در domain هم کار کنه؟

Saeed_m_Farid
شنبه 20 خرداد 1391, 09:15 صبح
"فرکانس استفاده از هر مراجعه به هر : ASCII name را شمارش کند"
یک سوال دیگه - چطور میشه کاری کرد که DNS ی که دارم علاوه بر workgroup در domain هم کار کنه؟



برداشتی ندارم :(
یه namespace هست برای اینکار که توش Domain (http://msdn.microsoft.com/en-us/library/system.directoryservices.activedirectory.domain.as px) داره: System.DirectoryServices.ActiveDirectory (http://msdn.microsoft.com/en-us/library/system.directoryservices.activedirectory.aspx) شما کافیه از تابع GetComputerDomain (http://msdn.microsoft.com/en-us/library/system.directoryservices.activedirectory.domain.ge tcomputerdomain.aspx) استفاده کنید، اگه به domain ای وصل نباشید ActiveDirectoryObjectNotFoundException (http://msdn.microsoft.com/en-us/library/system.directoryservices.activedirectory.activedir ectoryobjectnotfoundexception.aspx) میگیرین!