Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 19.01.2020, 16:36   #1
oxy-fox
Пользователь
 
Аватар для oxy-fox
 
Регистрация: 24.02.2009
Сообщений: 11
Вопрос Реализация Tracert (Socket, ICMP)

Добрый день!
Задача заключается в следующем: нужно сделать реализацию "tracert" не используя готовые классы.
Нашел подходящий мне исходник, немного его переделал, но он не работает (ни исходный, ни мой).
В чём может быть ошибка? Как её можно исправить?

Если закомментировать строчку
Код:
host.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.IpTimeToLive, i);
то программа работает по сути, как обычный ping

Код:
using System;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Text;
 
namespace Tracert
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        void Tracert(String remoteHost)
        {
            byte[] data = new byte[1024];
            int recv = 0;
            Socket host = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);
            IPHostEntry iphe = Dns.Resolve(remoteHost);
            IPEndPoint iep = new IPEndPoint(iphe.AddressList[0], 0);
            EndPoint ep = (EndPoint)iep;
            ICMP packet = new ICMP();
 
            packet.Type = 0x08;
            packet.Code = 0x00;
            packet.Checksum = 0;
            Buffer.BlockCopy(BitConverter.GetBytes(1), 0, packet.Message, 0, 2);
            Buffer.BlockCopy(BitConverter.GetBytes(1), 0, packet.Message, 2, 2);
            data = Encoding.ASCII.GetBytes("test packet");
            Buffer.BlockCopy(data, 0, packet.Message, 4, data.Length);
            packet.MessageSize = data.Length + 4;
            int packetsize = packet.MessageSize + 4;
 
            UInt16 chcksum = packet.getChecksum();
            packet.Checksum = chcksum;
 
            host.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 3000);
 
            int badcount = 0;
 
            for (int i = 1; i < 256; i++)
            {
                host.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.IpTimeToLive, i);
 
                DateTime timestart = DateTime.Now;
                host.SendTo(packet.getBytes(), packetsize, SocketFlags.None, iep);
                try
                {
                    data = new byte[1024];
                    recv = host.ReceiveFrom(data, ref ep);
                    TimeSpan timestop = DateTime.Now - timestart;
                    ICMP response = new ICMP(data, recv);
 
                    if (response.Type == 11)
                    {
                        richTextBox1.Text += i + ": " + ep.ToString() + " " + (timestop.Milliseconds.ToString());
                    }
                    
                    if (response.Type == 0)
                    {
                        richTextBox1.Text += ep.ToString() + " достигнут за " + i + " прыжков, " + (timestop.Milliseconds.ToString()) + "мс\n";
                        break;
                    }
 
                    badcount = 0;
                }
                catch (SocketException)
                {
                    richTextBox1.Text += i + ": нет ответа от " + ep + " (" + iep + ") - " + Convert.ToString(host.Ttl) + "\n";
                    badcount++;
 
                    if (badcount == 5)
                    {
                        richTextBox1.Text += "Не удалось установить соединение\n";
                        break;
                    }
                }
            }
            host.Close();
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            Tracert(textBox1.Text);
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            richTextBox1.Clear();
        }
    }
 
    class ICMP
    {
        public byte Type;
        public byte Code;
        public UInt16 Checksum;
        public int MessageSize;
        public byte[] Message = new byte[1024];
 
        public ICMP()
        {
        }
 
        public ICMP(byte[] data, int size)
        {
            Type = data[20];
            Code = data[21];
            Checksum = BitConverter.ToUInt16(data, 22);
            MessageSize = size - 24;
            Buffer.BlockCopy(data, 24, Message, 0, MessageSize);
        }
 
        public byte[] getBytes()
        {
            byte[] data = new byte[MessageSize + 9];
            Buffer.BlockCopy(BitConverter.GetBytes(Type), 0, data, 0, 1);
            Buffer.BlockCopy(BitConverter.GetBytes(Code), 0, data, 1, 1);
            Buffer.BlockCopy(BitConverter.GetBytes(Checksum), 0, data, 2, 2);
            Buffer.BlockCopy(Message, 0, data, 4, MessageSize);
            return data;
        }
 
        public UInt16 getChecksum()
        {
            UInt32 chcksm = 0;
            byte[] data = getBytes();
            int packetsize = MessageSize + 8;
            int index = 0;
 
            while (index < packetsize)
            {
                chcksm += Convert.ToUInt32(BitConverter.ToUInt16(data, index));
                index += 2;
            }
            chcksm = (chcksm >> 16) + (chcksm & 0xffff);
            chcksm += (chcksm >> 16);
            return (UInt16)(~chcksm);
        }
    }
 
}
oxy-fox вне форума Ответить с цитированием
Старый 19.01.2020, 17:28   #2
Black Fregat
Программист
Участник клуба
 
Аватар для Black Fregat
 
Регистрация: 23.06.2009
Сообщений: 1,772
По умолчанию

Вырезал консольный кусок - работает, что-то делает, но только через sudo
Попробуйте запустить от имени администратора
Black Fregat вне форума Ответить с цитированием
Старый 19.01.2020, 18:20   #3
oxy-fox
Пользователь
 
Аватар для oxy-fox
 
Регистрация: 24.02.2009
Сообщений: 11
По умолчанию

От имени администратора тоже самое. Оно, что-то делает) с закомментированой строчкой, о которой я написал, работает по принципу пинг.
Изображения
Тип файла: png 2020-01-19 (2).png (13.3 Кб, 7 просмотров)

Последний раз редактировалось oxy-fox; 19.01.2020 в 18:26.
oxy-fox вне форума Ответить с цитированием
Старый 19.01.2020, 20:14   #4
oxy-fox
Пользователь
 
Аватар для oxy-fox
 
Регистрация: 24.02.2009
Сообщений: 11
По умолчанию

Все заработало)) просто надо было выключить брандмауэр.
oxy-fox вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
протокол icmp jofri Помощь студентам 1 18.04.2013 13:12
tracert с ведением лога kostazs Помощь студентам 0 10.10.2012 18:16
Trace ICMP metoflex C/C++ Сетевое программирование 5 28.02.2011 02:51
Tracert в C# Лубышев Помощь студентам 3 18.09.2009 08:59
ICMP-сообщения Черничный Работа с сетью в Delphi 3 22.09.2008 22:06