قطعه برنامه بررسی مشبکه بودن گراف بهمراه سورس

در قطعه برنامه تهیه شده، مشخصات گراف را در قالب یک ماتریس به برنامه داده و برنامه اعلام می‌کند که این گراف مشبکه هست یا خیر.




تعریف مشبکه در ریاضیات گسسته

مجموعه‌ای با ترتیب جزئی (A, R) را یک مشبکه گویند هرگاه هر زیر مجموعه دو عضوی از این مجموعه دارای LUB یا Least Upper Bound و GLB یا Greatest Lower Bound باشد.


کد برنامه

کد اصلی برنامه کلاس Graph می‌باشد که به صورت زیر پیاده سازی شده است:


فایل Graph.cs

using System;
using System.Collections.Generic;
using System.Linq;

namespace LatticeGraph
{
    public class Graph
    {
        private readonly int[,] _matrix;
        private List<List<int>> _lowerPaths;
        private List<List<int>> _upperPaths;
        private List<int> _currentPath;
        private Dictionary<int, int> _nodesLevel;
        private readonly int _nodeCount;

        public Graph(int[,] matrix)
        {
            _matrix = matrix;
            _nodeCount = (int)Math.Sqrt(_matrix.Length);
        }

        public Dictionary<int, int> NodesLevel
        {
            get { return _nodesLevel; }
        }

        public bool IsLattice()
        {
            CalculateNodeLevels();

            for (var i = 0; i < _nodeCount; i++)
            {
                for (var j = 0; j < _nodeCount; j++)
                {
                    if (i == j) continue;
                    var lub = GetLub(i, j);
                    if (!checkLub(lub)) return false;
                    var glb = GetGlb(i, j);
                    if (!checkGlb(glb)) return false;
                }
            }
            return true;
        }

        private bool checkGlb(List<Junction> glb)
        {
            if (glb == null) return false;
            if (glb.Count == 1) return true;

            var glbNodes = glb.Select(x => x.Node).ToList();
            var levels = _nodesLevel.Where(x => glbNodes.Contains(x.Key)).ToList();
            var maxValue = levels.Max(x => x.Value);
            return levels.Count(x => x.Value == maxValue) == 1;
        }

        private bool checkLub(List<Junction> lub)
        {
            if (lub == null) return false;
            if (lub.Count == 1) return true;

            var glbNodes = lub.Select(x => x.Node).ToList();
            var levels = _nodesLevel.Where(x => glbNodes.Contains(x.Key)).ToList();
            var minValue = levels.Min(x => x.Value);
            return levels.Count(x => x.Value == minValue) == 1;
        }

        public void CalculateNodeLevels()
        {
            _nodesLevel = new Dictionary<int, int>();
            for (int i = 0; i < _nodeCount; i++)
            {
                var lowerPaths = LowerPaths(i);
                var maxPath = lowerPaths.Max(x => x.Count);
                _nodesLevel.Add(i, maxPath);
            }
        }

        public List<Junction> GetGlb(int i, int j)
        {
            var iLowerPaths = LowerPaths(i);
            var jLowerPaths = LowerPaths(j);

            var pathJunctions = new List<Junction>();

            foreach (var iPath in iLowerPaths)
            {
                foreach (var jPath in jLowerPaths)
                {
                    for (var x = 0; x < iPath.Count; x++)
                    {
                        var junctionFounded = false;
                        for (var y = 0; y < jPath.Count; y++)
                        {
                            if (iPath[x] != jPath[y]) continue;
                            pathJunctions.Add(new Junction(iPath[x], x));
                            junctionFounded = true;
                            break;
                        }
                        if (junctionFounded)
                        {
                            break;
                        }
                    }
                }
            }

            if (pathJunctions.Count <= 0) return null;
            var minPath = pathJunctions.Min(x => x.PathPartCount);
            return pathJunctions.Where(x => x.PathPartCount == minPath)
                .DistinctBy(d => new { d.Node, d.PathPartCount })
                .ToList();
        }

        public List<List<int>> LowerPaths(int node)
        {
            _lowerPaths = new List<List<int>>();
            _currentPath = new List<int>();
            GetLowerPaths(node);
            return _lowerPaths;
        }

        public void GetLowerPaths(int node)
        {
            if (_currentPath.Count > _nodeCount)
            {
                throw new Exception("به نظر میرسد گراف هاس نمی‌باشد");
            }
            _currentPath.Add(node);

            var childNodes = getChildNodes(node);
            if (childNodes.Count == 0)
            {
                var path = new List<int>(_currentPath);
                _lowerPaths.Add(path);
            }
            else
            {
                foreach (var childNode in childNodes)
                {
                    GetLowerPaths(childNode);
                }
            }
            _currentPath.RemoveAt(_currentPath.Count - 1);
        }

        public List<List<int>> UpperPaths(int node)
        {
            _upperPaths = new List<List<int>>();
            _currentPath = new List<int>();
            GetUpperPaths(node);
            return _upperPaths;
        }

        public void GetUpperPaths(int node)
        {
            if (_currentPath.Count > _nodeCount)
            {
                throw new Exception("به نظر میرسد گراف هاس نمی‌باشد");
            }
            _currentPath.Add(node);

            var parentNodes = getParentNodes(node);
            if (parentNodes.Count == 0)
            {
                var path = new List<int>(_currentPath);
                _upperPaths.Add(path);
            }
            else
            {
                foreach (var parentNode in parentNodes)
                {
                    GetUpperPaths(parentNode);
                }
            }
            _currentPath.RemoveAt(_currentPath.Count - 1);
        }

        private List<int> getChildNodes(int node)
        {
            var result = new List<int>();
            for (var i = node; i < _nodeCount; i++)
            {
                if (i != node && _matrix[i, node] == 1)
                {
                    result.Add(i);
                }
            }
            return result;
        }

        private List<int> getParentNodes(int node)
        {
            var result = new List<int>();
            for (var i = 0; i < _nodeCount; i++)
            {
                if (i != node && _matrix[node, i] == 1)
                {
                    result.Add(i);
                }
            }
            return result;
        }

        public List<Junction> GetLub(int i, int j)
        {
            var iUpperPaths = UpperPaths(i);
            var jUpperPaths = UpperPaths(j);

            var pathJunctions = new List<Junction>();

            foreach (var iPath in iUpperPaths)
            {
                foreach (var jPath in jUpperPaths)
                {
                    for (var x = 0; x < iPath.Count; x++)
                    {
                        var junctionFounded = false;
                        for (var y = 0; y < jPath.Count; y++)
                        {
                            if (iPath[x] != jPath[y]) continue;
                            pathJunctions.Add(new Junction(iPath[x], x));
                            junctionFounded = true;
                            break;
                        }
                        if (junctionFounded)
                        {
                            break;
                        }
                    }
                }
            }

            if (pathJunctions.Count <= 0) return null;
            var minPath = pathJunctions.Min(x => x.PathPartCount);
            return pathJunctions.Where(x => x.PathPartCount == minPath)
                .DistinctBy(d => new { d.Node, d.PathPartCount })
                .ToList();
        }
    }
}


فایل Junction.cs

namespace LatticeGraph
{
    public class Junction
    {
        public Junction(int node, int pathPartCount)
        {
            Node = node;
            PathPartCount = pathPartCount;
        }

        public Junction()
        {
        }

        public int Node { get; set; }
        public int PathPartCount { get; set; }
    }
}


کد آزمون واحد برنامه

using System;
using System.Collections.Generic;
using LatticeGraph;
using NUnit.Framework;

namespace TestProject
{
    [TestFixture]
    public class TestLatticeGraph
    {
        private int[,] _matrix;
        private int[,] _matrix_2;

        [SetUp]
        public void Setup()
        {
            _matrix = new[,]
            {
                {0, 0, 0, 0, 0, 0},
                {1, 0, 0, 0, 0, 0},
                {1, 0, 0, 0, 0, 0},
                {0, 1, 0, 0, 0, 0},
                {0, 1, 1, 0, 0, 0},
                {0, 0, 0, 1, 1, 0}
            };

            _matrix_2 = new[,]
            {
                {0, 0, 0, 0, 0, 0, 0},
                {1, 0, 0, 0, 0, 0, 0},
                {1, 0, 0, 0, 0, 0, 0},
                {1, 0, 0, 0, 0, 0, 0},
                {0, 1, 0, 1, 0, 0, 0},
                {0, 0, 1, 1, 0, 0, 0},
                {0, 0, 0, 0, 1, 1, 0}
            };
        }

        [Test]
        public void Test_Is_Moshabbakeh()
        {
            var graph = new Graph(_matrix);
            Assert.True(graph.IsLattice());

            _matrix[3, 2] = 1; // Make graph non lattice

            graph = new Graph(_matrix);
            Assert.False(graph.IsLattice());
        }

        [Test]
        public void Test_Get_Lower_Paths()
        {
            var graph = new Graph(_matrix);
            var lowerPaths = graph.LowerPaths(1);
            Assert.AreEqual(2, lowerPaths.Count);
            Assert.AreEqual(3, lowerPaths[0].Count);
            Assert.AreEqual(3, lowerPaths[1].Count);

            Assert.AreEqual(new List<int>() { 1, 3, 5 }, lowerPaths[0]);
            Assert.AreEqual(new List<int>() { 1, 4, 5 }, lowerPaths[1]);

            graph = new Graph(_matrix);
            lowerPaths = graph.LowerPaths(0);
            Assert.AreEqual(3, lowerPaths.Count);

            Assert.AreEqual(new List<int>() { 0, 1, 3, 5 }, lowerPaths[0]);
            Assert.AreEqual(new List<int>() { 0, 1, 4, 5 }, lowerPaths[1]);
            Assert.AreEqual(new List<int>() { 0, 2, 4, 5 }, lowerPaths[2]);
        }

        [Test]
        public void Test_Get_GLB_On_Lattice_Graph()
        {
            var graph = new Graph(_matrix);
            var glb = graph.GetGlb(1, 2);
            Assert.AreEqual(1, glb.Count);
            Assert.AreEqual(4, glb[0].Node);
            Assert.AreEqual(1, glb[0].PathPartCount);

            glb = graph.GetGlb(2, 1);
            Assert.AreEqual(1, glb.Count);
            Assert.AreEqual(4, glb[0].Node);
            Assert.AreEqual(1, glb[0].PathPartCount);

            glb = graph.GetGlb(2, 3);
            Assert.AreEqual(1, glb.Count);
            Assert.AreEqual(5, glb[0].Node);
            Assert.AreEqual(2, glb[0].PathPartCount);

            glb = graph.GetGlb(3, 2);
            Assert.AreEqual(1, glb.Count);
            Assert.AreEqual(5, glb[0].Node);
            Assert.AreEqual(1, glb[0].PathPartCount);

            glb = graph.GetGlb(0, 5);
            Assert.AreEqual(1, glb.Count);
            Assert.AreEqual(5, glb[0].Node);
            Assert.AreEqual(3, glb[0].PathPartCount);
        }

        [Test]
        public void Test_Get_GLB_On_None_Lattice_Graph()
        {
            _matrix[3, 2] = 1; //Make matrix non lattice

            var graph = new Graph(_matrix);
            var glb = graph.GetGlb(1, 2);
            Assert.AreEqual(2, glb.Count);
            Assert.AreEqual(3, glb[0].Node);
            Assert.AreEqual(1, glb[0].PathPartCount);

            Assert.AreEqual(4, glb[1].Node);
            Assert.AreEqual(1, glb[1].PathPartCount);
        }

        [Test]
        public void Test_Get_Upper_Paths()
        {
            var graph = new Graph(_matrix);
            var upperPaths = graph.UpperPaths(4);
            Assert.AreEqual(2, upperPaths.Count);
            Assert.AreEqual(3, upperPaths[0].Count);
            Assert.AreEqual(3, upperPaths[1].Count);

            Assert.AreEqual(new List<int>() { 4, 1, 0 }, upperPaths[0]);
            Assert.AreEqual(new List<int>() { 4, 2, 0 }, upperPaths[1]);

            graph = new Graph(_matrix);
            upperPaths = graph.UpperPaths(5);
            Assert.AreEqual(3, upperPaths.Count);

            Assert.AreEqual(new List<int>() { 5, 3, 1, 0 }, upperPaths[0]);
            Assert.AreEqual(new List<int>() { 5, 4, 1, 0 }, upperPaths[1]);
            Assert.AreEqual(new List<int>() { 5, 4, 2, 0 }, upperPaths[2]);
        }

        [Test]
        public void Test_Get_LUB_On_Lattice_Graph()
        {
            var graph = new Graph(_matrix);
            var lub = graph.GetLub(3, 4);
            Assert.AreEqual(1, lub.Count);
            Assert.AreEqual(1, lub[0].Node);
            Assert.AreEqual(1, lub[0].PathPartCount);

            lub = graph.GetLub(4, 3);
            Assert.AreEqual(1, lub.Count);
            Assert.AreEqual(1, lub[0].Node);
            Assert.AreEqual(1, lub[0].PathPartCount);

            lub = graph.GetLub(2, 3);
            Assert.AreEqual(1, lub.Count);
            Assert.AreEqual(0, lub[0].Node);
            Assert.AreEqual(1, lub[0].PathPartCount);

            lub = graph.GetLub(0, 5);
            Assert.AreEqual(1, lub.Count);
            Assert.AreEqual(0, lub[0].Node);
            Assert.AreEqual(0, lub[0].PathPartCount);
        }

        [Test]
        public void Test_Get_LUB_On_None_Lattice_Graph()
        {
            _matrix[3, 2] = 1; //Make matrix non lattice

            var graph = new Graph(_matrix);
            var glb = graph.GetLub(3, 4);
            Assert.AreEqual(2, glb.Count);
            Assert.AreEqual(1, glb[0].Node);
            Assert.AreEqual(1, glb[0].PathPartCount);

            Assert.AreEqual(2, glb[1].Node);
            Assert.AreEqual(1, glb[1].PathPartCount);
        }

        [Test]
        public void Test_Is_Moshabbakeh_2()
        {
            var graph = new Graph(_matrix_2);
            Assert.True(graph.IsLattice());
        }

        [Test]
        public void Test_Get_GLB_On_Lattice_Graph_2()
        {

            var graph = new Graph(_matrix_2);
            var glb = graph.GetGlb(0, 5);
            Assert.AreEqual(1, glb.Count);
            Assert.AreEqual(5, glb[0].Node);
            Assert.AreEqual(2, glb[0].PathPartCount);

            glb = graph.GetGlb(4, 2);
            Assert.AreEqual(1, glb.Count);
            Assert.AreEqual(6, glb[0].Node);
            Assert.AreEqual(1, glb[0].PathPartCount);

            glb = graph.GetGlb(3, 2);
            Assert.AreEqual(1, glb.Count);
            Assert.AreEqual(5, glb[0].Node);
            Assert.AreEqual(1, glb[0].PathPartCount);
        }

        [Test]
        public void Test_Calculate_Node_level()
        {
            var graph = new Graph(_matrix);
            graph.CalculateNodeLevels();
            Assert.AreEqual(6, graph.NodesLevel.Count);
            int i;
            
            graph.NodesLevel.TryGetValue(5, out i);
            Assert.AreEqual(1, i);

            graph.NodesLevel.TryGetValue(4, out i);
            Assert.AreEqual(2, i);

            graph.NodesLevel.TryGetValue(3, out i);
            Assert.AreEqual(2, i);

            graph.NodesLevel.TryGetValue(2, out i);
            Assert.AreEqual(3, i);

            graph.NodesLevel.TryGetValue(1, out i);
            Assert.AreEqual(3, i);

            graph.NodesLevel.TryGetValue(0, out i);
            Assert.AreEqual(4, i);
        }
    }
}


دریافت فایل

فایل اجرایی برنامه بهمراه نمونه گراف مشبکه


سورس کامل برنامه + آزمون واحد

تنظیم IP کارت شبکه از طریق کدنویسی

توسط قطعه کد زیر می‌توانید از طریق کدنویسی IP Address و Default Getway و همچنین DNS Server مربوط به کارت شبکه مورد نظرتان را تغییر دهید.


این برنامه ابتدا مشخصات کارت شبکه مورد نظر را خوانده و با مشخصاتی که در فایل کانفیگ برنامه تعیین شده است تطابق می‌دهد. در صورتی‌که اطلاعات مغایرت داشته باشد، مشخصات داخل فایل کانفیگ را برای کارت شبکه مورد نظر اعمال می‌کند.

این قطعه کد، زمانی مفید است که بعنوان مثال شما یک سرور اختصاصی (VPS) دارید که به صورت Remote به آن دسترسی دارید. اگر به هر علت IP این سرور تغییر کند، سرور به کلی از دسترس خارج می‌شود و باید به شرکت ارائه دهنده سرویس تماس بگیرید تا مجدداً  IP سرور را تنظیم کنند.

 این برنامه را می‌توان در یک Task ویندوزی تنظیم کرد که در بازه‌های معین اجرا شود تا در صورتی که سرور از دسترس خارج شده باشد، با تنظیم مجدد IP سرور در دسترس قرار گیرد.

کد اصلی برنامه


using System;
using System.Collections.Generic;
using System.Configuration;
using System.Threading;

namespace SetIP
{
    class Program
    {
        private const int TryCount = 20;

        static void Main(string[] args)
        {
            try
            {
                var i = 0;
                var isEqual = false;
                while (!isEqual && i < TryCount)
                {
                    Console.WriteLine("Checking number: {0}", i + 1);
                    isEqual = checkAdapter();
                    i++;
                    Thread.Sleep(5000);
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        private static bool checkAdapter()
        {
            var networkAdapterHelper = new NetworkAdapterHelper();

            var baseAdapter = new Adapter()
            {
                AdaptorName = ConfigurationManager.AppSettings["EthernetName"],
                Ip = ConfigurationManager.AppSettings["IP"],
                Subnet = ConfigurationManager.AppSettings["SubnetMask"],
                Getway = ConfigurationManager.AppSettings["DefaultGetway"],
                DnsServer = ConfigurationManager.AppSettings["DnsServer"],
                AlternativeDns = ConfigurationManager.AppSettings["AlterNativeDnsServer"]
            };

            networkAdapterHelper.Execute(new List<string>()
            {
                String.Format("netsh interface set interface name=\"{0}\" admin=enabled", baseAdapter.AdaptorName)
            }); 

            var currentAdapter = networkAdapterHelper.GetAdapterInformation(baseAdapter.AdaptorName);
            if (currentAdapter == null)
            {
                Console.WriteLine("Adapter not found!");
                return false;
            }
            if (networkAdapterHelper.IsEqual(currentAdapter, baseAdapter))
                return true;
            networkAdapterHelper.SetEthernetInformation(baseAdapter);
            return false;
        }
    }
}


کلاس Adapter

namespace SetIP
{
    public class Adapter
    {
        public string AdaptorName;
        public string Ip;
        public string Subnet;
        public string Getway;
        public string DnsServer;
        public string AlternativeDns;

        public Adapter()
        {
        }

        public Adapter(string adaptorName, string ip, string subnet, string getway, string dnsServer, string alternativeDns)
        {
            this.AdaptorName = adaptorName;
            this.Ip = ip;
            this.Subnet = subnet;
            this.Getway = getway;
            this.DnsServer = dnsServer;
            this.AlternativeDns = alternativeDns;
        }
    }
}


کلاس کمکی NetworkAdapterHelper

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Net.Sockets;

namespace SetIP
{
    public class NetworkAdapterHelper
    {
        public Adapter GetAdapterInformation(string adapterName)
        {
            var adapter = NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(x => x.Name == adapterName);
            if (adapter == null)
            {
                Console.WriteLine("Adapter {0} not found!", adapterName);
                return null;
            }

            var ip = getIpAddress(adapter);
            if (String.IsNullOrEmpty(ip))
            {
                Console.WriteLine("Cannot grab IP address information!");
                return null;
            }

            //var subnet = unicastIpAddressInformation.IPv4Mask.ToString();
            var subnet = GetSubnetMask(adapter);

            var result = new Adapter()
            {
                AdaptorName = adapter.Name,
                Ip = ip,
                Subnet = subnet,
                Getway = GetDefaultGateway(adapter)
            };

            GetDnsAddresses(adapter, out result.DnsServer, out result.AlternativeDns);
            return result;
        }

        private string getIpAddress(NetworkInterface adapter)
        {
            UnicastIPAddressInformationCollection addresses = adapter.GetIPProperties().UnicastAddresses;
            var ipAddressInformation = addresses.FirstOrDefault(x => x.Address.AddressFamily == AddressFamily.InterNetwork);
            if (ipAddressInformation == null)
            {
                return null;
            }

            return ipAddressInformation.Address.ToString();
        }

        public string GetSubnetMask(NetworkInterface adapter)
        {
            var query =
                from properties in adapter.GetIPProperties().UnicastAddresses
                where properties.Address.AddressFamily == AddressFamily.InterNetwork && properties.IPv4Mask != null
                select properties.IPv4Mask;

            var firstOrDefault = query.FirstOrDefault();
            return firstOrDefault != null ? firstOrDefault.ToString() : "";
        }

        /// The Default Gateway's IP address as a string. 
        public string GetDefaultGateway(NetworkInterface adapter)
        {
            var defaultGateway =
            from props in adapter.GetIPProperties().GatewayAddresses
            select props.Address.ToString();

            return defaultGateway.First();
        }

        public void GetDnsAddresses(NetworkInterface adapter, out string dnsServer, out string alternative)
        {
            dnsServer = "";
            alternative = "";

            var dnsServers = adapter.GetIPProperties().DnsAddresses;

            if (dnsServers.Count <= 0) return;

            dnsServer = dnsServers[0].ToString();

            if (dnsServers.Count == 2)
            {
                alternative = dnsServers[1].ToString();
            }
        }

        public void SetEthernetInformation(Adapter adapter)
        {
            var commands = new List<string>
            {
                String.Format("netsh interface set interface name=\"{0}\" admin=enabled", adapter.AdaptorName),
                String.Format("netsh interface ip set address \"{0}\" static {1} {2} {3} 1", adapter.AdaptorName,
                    adapter.Ip, adapter.Subnet, adapter.Getway),
                String.Format("netsh interface ipv4 delete dnsservers \"{0}\" all", adapter.AdaptorName)
            };
            if (!String.IsNullOrEmpty(adapter.DnsServer))
            {
                commands.Add(String.Format("netsh interface ipv4 add dnsserver \"{0}\" address={1}", adapter.AdaptorName, adapter.DnsServer));
            }
            if (!String.IsNullOrEmpty(adapter.AlternativeDns))
            {
                
                commands.Add(String.Format("netsh interface ipv4 add dnsserver \"{0}\" address={1} index=2", adapter.AdaptorName, adapter.AlternativeDns));
            }
            Execute(commands);
        }

        public bool IsEqual(Adapter currentAdapter, Adapter baseAdapter)
        {
            return currentAdapter.Ip == baseAdapter.Ip
                   && currentAdapter.Subnet == baseAdapter.Subnet
                   && currentAdapter.Getway == baseAdapter.Getway
                   && currentAdapter.DnsServer == baseAdapter.DnsServer
                   && currentAdapter.AlternativeDns == baseAdapter.AlternativeDns;
        }

        public void Execute(List<string> commands)
        {
            var p = new Process();
            var info = new ProcessStartInfo
            {
                FileName = "cmd.exe",
                WindowStyle = ProcessWindowStyle.Hidden,
                RedirectStandardInput = true,
                UseShellExecute = false
            };

            p.StartInfo = info;
            p.Start();

            using (StreamWriter sw = p.StandardInput)
            {
                foreach (var command in commands)
                {
                    if (sw.BaseStream.CanWrite)
                    {
                        sw.WriteLine(command);
                    }
                }
            }
        }
    }
}


نمونه‌ای از فایل پیکربندی (کانفیگ) برنامه

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <add key="EthernetName" value="Ethernet" />
    <add key="IP" value="192.168.1.2" />
    <add key="SubnetMask" value="255.255.255.0" />
    <add key="DefaultGetway" value="192.168.1.1" />
    <add key="DnsServer" value="8.8.8.8" />
    <add key="AlterNativeDnsServer" value="8.8.4.4" />
  </appSettings>
</configuration>


دریافت سورس کامل برنامه

راه‌اندازی مجدد مودم ADSL از طریق کدنویسی

یکی از معایب اینترنت‌های ADSL معمولی عدم پایداری اتصال به اینترنت می‌باشد. یعنی زمانی که مودم ADSL برای ساعات طولانی مدت (معمولاً بیشتر از 24 ساعت) روشن باشد، غالباً اینترنت قطع شده و نیاز به راه‌اندازی مجدد مودم برای ایجاد سشن جدید و اتصال مجدد به اینترنت می‌باشد.

چقدر خوب بود اگر می‌شد این کار بصورت اتوماسیون انجام می‌گرفت.

برای انجام این کار قطعه کدی تهیه کرده‌ام که بصورت متوالی اتصال به اینترنت را آزمایش کرده و در صورت عدم اتصال به اینترنت مودم را خاموش و روشن می‌کند.

نکته‌ای که در اینجا حائز اهمیت است نحوه خاموش و روشن کردن مودم از طریق کدنویسی می‌باشد.

غالباً برای انجام اجرای دستورات مودم یا روترها از Telnet استفاده می‌شود. به این شکل که از طریق خط فرمان با دستور Telnet به مودم متصل شده و پس از وارد کردن نام کاربری و رمز عبور، دستور مورد نظر را مثل دستور Reboot رای در خط فرمان تایپ کرده و اینتر زده و بدین ترتیب مودم راه‌اندازی مجدد می‌شود.

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

نحوه اتصال به مودم از طریق برنامه‌نویسی

ابتدا نصاب پایتون برای ویندوز را از این آدرس دریافت کرده و آن را نصب نمایید. نصب پایتون نکته‌ی خاصی ندارد.

پس از نصب پایتون قطعه کد زیر را در فایلی با پسوند "py" ذخیره می‌‌کنید.

برای تست اتصال به اینترنت از متد زیر استفاده می‌کنیم:

def pingHost():
    hostname = "www.google.com"
    response = os.system("ping " + hostname)

    if response == 0:
      return True
    else:
      return False

این قطعه کد یک Ping به یک هاست مانند گوگل زده و از این طریق وضعیت اتصال به اینترنت را تشخیص می‌دهد.

اگر به تعداد maxTry اتصال به اینترنت انجام نشود، توسط متد زیر مودم مجدداً راه‌اندازی می‌شود:

def rebootModem():
    try:
        print("Rebooting modem...")
        HOST = "192.168.1.1"
        user = b"admin"
        password = b"password"

        tn = telnetlib.Telnet(HOST)

        tn.read_until(b"Login: ")
        tn.write(user + b"\n")
        tn.read_until(b"Password: ")
        tn.write(password + b"\n")
        tn.read_until(b"> ")
        tn.write(b"reboot\n\n")
    except:
        print("Error!")

توسط این متد ابتدا به آی‌پی مودم که بصورت پیش‌فرض 192.168.1.1 می‌باشد، Telnet کرده و منتظر خط فرمان برای درخواست نام کاربری می‌ماند، یعنی منتظر مانده تا در خط فرمان عبارت "Login:" دیده شود:

        tn.read_until(b"Login: ")

پس از مشاهده عبارت Login برنامه نام کاربری را ارسال کرده و فشردن کلید اینتر را توسط کاراکتر "\n" شبیه‌سازی می‌کند:

        tn.write(user + b"\n")

بهمین ترتیب منتظر درخواست کلمه رمز شده و کلمه رمز را ارسال می‌کند و پس از ظاهر شدن اعلان خط فرمان مودم یعنی پس از دیده شدن کاراکتر "<" دستور "reboot" صادر شده و فشرده شدن کلید اینتر شبیه‌سازی می‌شود:

        tn.read_until(b"> ")
        tn.write(b"reboot\n\n")

کد کامل برنامه

import os
import time
import telnetlib
import datetime

maxTry = 3
shortDelay = 10
longDelay = 300
tryCount = 0

def pingHost():
    hostname = "www.google.com"
    response = os.system("ping " + hostname)

    if response == 0:
      return True
    else:
      return False

def rebootModem():
    try:
        print("Rebooting modem...")
        HOST = "192.168.1.1"
        user = b"admin"
        password = b"password"

        tn = telnetlib.Telnet(HOST)

        tn.read_until(b"Login: ")
        tn.write(user + b"\n")
        tn.read_until(b"Password: ")
        tn.write(password + b"\n")
        tn.read_until(b"> ")
        tn.write(b"reboot\n\n")
    except:
        print("Error!")

delayTime = longDelay

while True:
    if(pingHost() == False):
        delayTime = shortDelay
        if(tryCount == maxTry):
            rebootModem()
            tryCount = 0
            delayTime = longDelay
        else:
            tryCount+=1
    else:
        delayTime = longDelay
    time.sleep(delayTime)

اجرای برنامه

جهت اجرای برنامه به دو روش می‌توانید اقدام کنید:

1- برنامه IDLE که در مسیر All Program>Python x.x قرار دارد را اجرا کنید. از منوی File>Open فایل برنامه را بازکرده و کلید F5 را جهت اجرا بفشارید.

2- از طریق خط فرمان زیر:

C:\PythonXX\python.exe RebootModem.py

 

کد کامل برنامه را در قالب فایل پایتون دریافت کنید:

بهینه‌سازی آدرس‌های وبلاگ مبتنی بر Blogengine.NET

در پست قبلی به دلایل استفاده از حروف کوچک در آدرس‌های وب‌سایت اشاره شد. حال مسئله‌ای که وجود دارد این است که در حالتی که شما از سیستم‌های مدیریت محتوا (CMS) و یا سیستم‌های مدیریت وبلاگ (Blog Engine) استفاده می‌کنید چطور این امکان را به سایت خود اضافه کنید. بعنوان مثال افزودن این امکان را برای سیستم مدیریت وبلاگ Blogengine.NET بررسی خواهیم کرد.


آدرس‌های پیش‌فرض در Blogengine شامل حروف بزرگ می‌باشد. چون Blogengine بر پایه‌ی دات‌نت طراحی شده‌است و بر روی وب‌سرور IIS اجرا می‌شود، می‌توان از امکانات IIS جهت تبدیل آدرس‌ها به حروف کوچک استفاده کرد.


برای این منظور از ماژول URL Rewrite استفاده خواهیم کرد. URL Rewrite ماژولی است که توسط آن می‌توانید آدرس‌های درخواستی وب‌سایت خود را به آدرس دلخواهتان تغییر دهید.
آدرس دریافت ماژول URL Rewrite
پس از دریافت ماژول آن را نصب کنید و سپس کد زیر را به فایل وب‌کانفیگ وبلاگ اضافه کنید.

<system.webServer>
  <rewrite>
    <rules>
      <rule name="LowerCaseRule" stopProcessing="true">
        <match url="[A-Z]" ignoreCase="false" />
        <action type="Redirect" url="{ToLower:{URL}}" />
      </rule>
    </rules>
  </rewrite>
</system.webServer>

توضیح کد:
این کد تمامی آدرس‌های درخواستی را به حروف کوچک (Lowercase) تبدیل می‌کند.

یک مشکل بزرگ!
احتمالاً پس از اضافه کردن کد فوق قسمت‌هایی از وبلاگ شما از کار خواهد افتاد. خصوصاً بخش‌های مدیریت وبلاگتان از قبیل مشاهده لیست پست‌ها و نظرات و ...
این مشکل بخاطر این است که یک سری از سرویس‌های مدیریت وبلاگ حساس به حروف کوچک و بزرگ هستند.
برای رفع این مشکل باید صفحاتی که شامل صفحات مدیریت وبلاگتان می‌باشند، یعنی صفحاتی که پس از لاگین کردن با حساب مدیر وبلاگ قابل مشاهد هستند را از قسمت تغییر آدرس مستثنی کرد. بعلت اینکه این صفحات، صفحات عمومی نیستند پس نیازی هم به رتبه‌بندی این صفحات در موتورهای جستجو نیست.
بعلت اینکه نام کاربر در آدرس صفحات مدیریت وبلاگ وجود دارد، بعنوان مثال در آدرس http://www.weblog.com/admin/Posts.aspx نام کاربر (admin) وجود دارد، پس می‌توان تنظیم کرد که تمامی صفحاتی که در آنها کلمه "/admin/" و یا کلمه "/api/" وجود دارد نادیده گرفته شوند.
برای انجام این کار کد را به این شکل تغییر دهید:

<system.webServer>
  ...
  <rewrite>
    <rules>
      <rule name="LowerCaseRule" stopProcessing="true">
        <match url="[A-Z]" ignoreCase="false" />
        <conditions>
          <add input="{URL}" matchType="Pattern" pattern="^.*/admin/.*$" ignoreCase="false" negate="true" />
          <add input="{URL}" matchType="Pattern" pattern="^.*/api/.*$" ignoreCase="false" negate="true" />
        </conditions>
        <action type="Redirect" url="{ToLower:{URL}}" />
      </rule>
    </rules>
  </rewrite>
</system.webServer>


اجبار به استفاده از www در آدرس‌ها
یکی دیگر از مواردی که باعث اختلاف در آدرس‌های مشابه سایت می‌شود وجود یا عدم وجود www در آدرس سایت می‌باشد. برای افزودن خودکار www به تمامی آدرس‌های سایت نیز می‌توانید از ماژول URL Reweiter استفاده کرد.
برای این کار قطعه کد زیر را نیز به وب کانفیگ وبلاگ یا سایت خود اضافه کنید.
<system.webServer>
  ...
  <rewrite>
    <rules>
      ...
      <rule name="Add www" patternSyntax="Wildcard" stopProcessing="true">
        <match url="*" />
        <conditions>
          <add input="{HTTP_HOST}" pattern="www.yoursite.com" negate="true" />
        </conditions>
        <action type="Redirect" url="http://www.yoursite.com/{R:1}" />
      </rule>
    </rules>
  </rewrite>
</system.webServer>


حال اگر آدرس وبلاگ و یا سایت بصورت yoursite.com وارد شود بصورت خودکار به آدرس www.yoursite.com منتقل خواهد شد.

دلایل عدم استفاده از حروف بزرگ در آدرس‌های وب‌سایت

یکی از مسائل مهمی که در حین ایجاد یک وب‌سایت باید درنظر گرفته شود، استفاده از حروف کوچک در URLها می‌باشد. بعنوان مثال دو آدرس زیر را در نظر بگیرید:

http://www.example.com/about
http://www.example.com/About

هر دو آدرس به یک صفحه مشخص اشاره می‌کنند.  اما آدرسی که در آن تماماً حروف کوچک استفاده شده است، بهتر است. در ادامه به دلایل این مسئله می‌پردازیم.

پردازش آدرس‌ها در سرورهای مختلف متفاوت است

اگر وب‌سایت شما بر روی یک سرور ویندوزی باشد، هر دو آدرس http://www.example.com/about و http://www.example.com/About یکسان درنظر گرفته شده و به یک صفحه ��رجاع داده می‌شوند. ولی اگر سرور وب‌سایت شما لینوکسی باشد، آنگاه هر دو آدرس، دو آدرس مجزا در نظر گرفته می‌شود. یعنی یکی از آدرس‌ها به صفحه مورد نظر ارجاع داده می‌شود و آدرس دوم با خطای 404  (صفحه یافت نشد)  مواجه می‌شود!


داشتن دو آدرسی که به یک صفحه  اشاره می‌کند برای رتبه‌بندی موتورهای جستجو مناسب نمی‌باشد

همانطور که قبلاً اشاره کردیم اگرچه در سرورهای ویندوزی هر دو آدرس http://www.example.com/about و http://www.example.com/About به یک صفحه واحد ارجاع داده می‌شود اما موتورهای جستجو این دو آدرس را دو صفحه مجزا در نظر می‌گیرند که این از لحاظ رتبه‌بندی صفحه مورد نظر در موتورهای مناسب نیست و رتبه صفحه موردنظر کمتر از مقدار واقعی آن خواهد شد.


نتیجه‌گیری:

حتماً در حین طراحی و یا راه‌اندازی وب‌سایتتان این مسئله را در نظر داشته باشید که تمامی آدرس‌های وب‌سایتتان از حروف کوچک تشکیل شده باشد