Оченно странная ошибка

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Оченно странная ошибка

Сообщение Viper » 15.03.2006 (Ср) 12:15

Был такой код в VB 6
Код: Выделить всё

Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (Dest As Any, Src As Any, ByVal cb&)
Private Declare Function inet_addr Lib "ws2_32.dll" (ByVal addr As String) As Long
Private Declare Function gethostbyaddr Lib "ws2_32.dll" (addr As Long, ByVal addr_len As Long, ByVal addr_type As Long) As Long
Private Type hostent
    h_name As Long
    h_aliases As Long
    h_addrtype As Integer
    h_length As Integer
    h_addr_list As Long
End Type
Function GetNameByIP(ByVal sIP As String) As String
    Dim lAddress As Long
    Dim p As Long
    Dim HostName As String
    Dim Host As hostent
    lAddress = inet_addr(sIP)
    p = gethostbyaddr(lAddress, 4, PF_INET)
    If p <> 0 Then
        CopyMemory Host, ByVal p, Len(Host)
        HostName = String(256, 0)
        CopyMemory ByVal HostName, ByVal Host.h_name, 256
        GetNameByIP = Left(HostName, InStr(HostName, Chr(0)) - 1)
    End If
End Function


Работало все чудесно и замечательно для получения имени компа по его IP.

При переводе на VB.NET получился следующий код (с учетом имеющихся в VB.NET полезных фишек)
Код: Выделить всё

<StructLayout(LayoutKind.Sequential, pack:=1)> Private Structure hostent
        Public h_name As IntPtr
        Public h_aliases As IntPtr
        Public h_addrtype As Short
        Public h_length As Short
        Public h_addr_list As IntPtr
End Structure
<DllImport("Ws2_32.dll")> Private Function inet_addr(ByVal cp As String) As Integer
End Function
<DllImport("Ws2_32.dll")> Private Function gethostbyaddr(ByVal addr As Integer, ByVal len As Integer, ByVal type As Integer) As IntPtr
End Function
Public Function GetNameByIP(ByVal sIP As String) As String
        Try
            Dim address As Integer = inet_addr(sIP)
            If address <> INADDR_NONE Then
                Dim p As IntPtr = gethostbyaddr(address, 4, AF_INET)
                If Not p.Equals(IntPtr.Zero) Then
                    Dim host As hostent = CType(Marshal.PtrToStructure(p, GetType(hostent)), hostent)
                    Return Marshal.PtrToStringAnsi(host.h_name)
                End If
            End If
        Catch e As Exception
            Debug.WriteLine(e)
        End Try
End Function


Код по своей сути аналогичен, но в строке
Код: Выделить всё

Dim p As IntPtr = gethostbyaddr(address, 4, AF_INET)

происходит ошибка "System.NullReferenceException: Object reference not set to an instance of an object."

Бред полный... в каком месте там нулевая ссылка?:(

Кто-нить может что нибудь сказать по этому поводу?

З.Ы. Естественно, что при помощи методов класса DNS можно получить имя компа по его IP. Меня в данном случае волнует только происхождение этой ошибки... :(
Весь мир матрица, а мы в нем потоки байтов!

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 15.03.2006 (Ср) 12:39

Разобрался!

Кривые руки и позавчерашняя бессонная ночь виноваты. Объявление функции
Код: Выделить всё

<DllImport("Ws2_32.dll")> Private Function gethostbyaddr(ByVal addr As Integer, ByVal len As Integer, ByVal type As Integer) As IntPtr
End Function
должно быть
Код: Выделить всё

<DllImport("Ws2_32.dll")> Private Function gethostbyaddr(ByRef addr As Integer, ByVal len As Integer, ByVal type As Integer) As IntPtr
End Function


ибо addr должен быть именно адресом компа, а не указателем на него...

Тему можно прикрывать...
Весь мир матрица, а мы в нем потоки байтов!

Ramzes
Скромный человек
Скромный человек
Аватара пользователя
 
Сообщения: 5004
Зарегистрирован: 12.04.2003 (Сб) 11:59
Откуда: Из гробницы :)

Сообщение Ramzes » 15.03.2006 (Ср) 12:50

с учетом полезных фишек:
MSDN писал(а):Dns.GetHostByAddress -метод [Visual Basic]См. также
Dns - класс | Dns - члены | System.Net - пространство имен | Managed Extensions for C++ Programming
Язык
C#

C++

JScript

Visual Basic

Показать все
Возвращает сведения DNS о хосте для IP-адреса.

Список перегрузки
Создает экземпляр IPHostEntry из указанного IPAddress.

Поддерживается .NET Compact Framework.

[Visual Basic] Overloads Public Shared Function GetHostByAddress(IPAddress) As IPHostEntry
[C#] public static IPHostEntry GetHostByAddress(IPAddress);
[C++] public: static IPHostEntry* GetHostByAddress(IPAddress*);
[JScript] public static function GetHostByAddress(IPAddress) : IPHostEntry;
Создает экземпляр IPHostEntry из IP-адреса.

Поддерживается .NET Compact Framework.

[Visual Basic] Overloads Public Shared Function GetHostByAddress(String) As IPHostEntry
[C#] public static IPHostEntry GetHostByAddress(string);
[C++] public: static IPHostEntry* GetHostByAddress(String*);
[JScript] public static function GetHostByAddress(String) : IPHostEntry;
Пример
[Visual Basic, C#, C++] В следующем примере показано создание IPHostEntry из IPAddress.

[Visual Basic, C#, C++] Примечание. Этот пример иллюстрирует использование одной из перегруженных версий GetHostByAddress. Другие примеры можно найти в разделах, посвященных перегрузке.
[Visual Basic]
Public Sub DisplayHostAddress(IpAddressString As [String])
Try
Dim hostIPAddress As IPAddress = IPAddress.Parse(IpAddressString)

' Call the GetHostByAddress(IPAddress) method, passing an IPAddress object as an argument
' to obtain an IPHostEntry instance, containing address information for the specified host.

Dim hostInfo As IPHostEntry = Dns.GetHostByAddress(hostIPAddress)
' Get the IP address list that resolves to the host names contained in
' the Alias property.
Dim address As IPAddress() = hostInfo.AddressList
' Get the alias names of the above addresses in the IP address list.
Dim [alias] As [String]() = hostInfo.Aliases

Console.WriteLine(("Host name : " + hostInfo.HostName))
Console.WriteLine(ControlChars.Cr + "Aliases :")
Dim index As Integer
For index = 0 To [alias].Length - 1
Console.WriteLine([alias](index))
Next index
Console.WriteLine(ControlChars.Cr + "IP address list : ")

For index = 0 To address.Length - 1
Console.WriteLine(address(index))
Next index

Catch e As SocketException
Console.WriteLine("SocketException caught!!!")
Console.WriteLine(("Source : " + e.Source))
Console.WriteLine(("Message : " + e.Message))

Catch e As FormatException
Console.WriteLine("FormatException caught!!!")
Console.WriteLine(("Source : " + e.Source))
Console.WriteLine(("Message : " + e.Message))

Catch e As ArgumentNullException
Console.WriteLine("ArgumentNullException caught!!!")
Console.WriteLine(("Source : " + e.Source))
Console.WriteLine(("Message : " + e.Message))

Catch e As Exception
Console.WriteLine("Exception caught!!!")
Console.WriteLine(("Source : " + e.Source))
Console.WriteLine(("Message : " + e.Message))
End Try
End Sub 'DisplayHostAddress

MSDN писал(а):Dns.GetHostByName -метод [Visual Basic]См. также
Dns - класс | Dns - члены | System.Net - пространство имен | Dns Members (Visual J# Syntax) | Managed Extensions for C++ Programming
Требования
Платформы: Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, Семейство Windows Server 2003, .NET Compact Framework - Windows CE .NET, Common Language Infrastructure (CLI) Standard

Безопасность .NET Framework:

DnsPermission на доступ к DNS. Связанное перечисление: PermissionState.Unrestricted
Язык
C#

C++

JScript

Visual Basic

Показать все
Возвращает сведения DNS для указанного DNS-имени хоста.

[Visual Basic]
Public Shared Function GetHostByName( _
ByVal hostName As String _
) As IPHostEntry

[C#]
public static IPHostEntry GetHostByName(
string hostName
);

[C++]
public: static IPHostEntry* GetHostByName(
String* hostName
);

[JScript]
public static function GetHostByName(
hostName : String
) : IPHostEntry;

Параметры
hostName
Строка, содержащая DNS-имя хоста.
Возвращаемое значение
Объект IPHostEntry, содержащий сведения о хосте для адреса, указанного в hostName.

Исключения
Тип исключения Условие
ArgumentNullException Значение параметра hostName — пустая ссылка (Nothing в Visual Basic).
SocketException При преобразовании hostName возникает ошибка.
SecurityException У вызывающего оператора не имеется разрешения на доступ к сведениям DNS.

Примечания
Метод GetHostByName запрашивает у DNS-сервера Интернета сведения о хосте.

Для асинхронного доступа к сведениям DNS используйте методы BeginGetHostByName и EndGetHostByName.

Пример
[Visual Basic, C#, C++] В следующем примере показано применение метода GetHostByName для получения сведений DNS для указанного DNS-имени хоста.

[Visual Basic]
Public Sub DisplayHostName(hostName As [String])
Try
' Call the GetHostByName method, passing a DNS style host name(for example,
' "www.contoso.com") as an argument to obtain an IPHostEntry instance, that
' contains information for the specified host.

Dim hostInfo As IPHostEntry = Dns.GetHostByName(hostName)
' Get the IP address list that resolves to the host names contained in
' the Alias property.
Dim address As IPAddress() = hostInfo.AddressList
' Get the alias names of the the addresses in the IP address list.
Dim [alias] As [String]() = hostInfo.Aliases

Console.WriteLine(("Host name : " + hostInfo.HostName))
Console.WriteLine(ControlChars.Cr + "Aliases : ")
Dim index As Integer
For index = 0 To [alias].Length - 1
Console.WriteLine([alias](index))
Next index
Console.WriteLine(ControlChars.Cr + "IP address list : ")

For index = 0 To address.Length - 1
Console.WriteLine(address(index))
Next index
Catch e As SocketException
Console.WriteLine("SocketException caught!!!")
Console.WriteLine(("Source : " + e.Source))
Console.WriteLine(("Message : " + e.Message))
Catch e As ArgumentNullException
Console.WriteLine("ArgumentNullException caught!!!")
Console.WriteLine(("Source : " + e.Source))
Console.WriteLine(("Message : " + e.Message))
Catch e As Exception
Console.WriteLine("Exception caught!!!")
Console.WriteLine(("Source : " + e.Source))
Console.WriteLine(("Message : " + e.Message))
End Try

[C#]
try
{
IPHostEntry hostInfo = Dns.GetHostByName(hostName);
// Get the IP address list that resolves to the host names contained in the
// Alias property.
IPAddress[] address = hostInfo.AddressList;
// Get the alias names of the addresses in the IP address list.
String[] alias = hostInfo.Aliases;

Console.WriteLine("Host name : " + hostInfo.HostName);
Console.WriteLine("\nAliases : ");
for(int index=0; index < alias.Length; index++) {
Console.WriteLine(alias[index]);
}
Console.WriteLine("\nIP address list : ");
for(int index=0; index < address.Length; index++) {
Console.WriteLine(address[index]);
}
}
catch(SocketException e)
{
Console.WriteLine("SocketException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
catch(ArgumentNullException e)
{
Console.WriteLine("ArgumentNullException caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}
catch(Exception e)
{
Console.WriteLine("Exception caught!!!");
Console.WriteLine("Source : " + e.Source);
Console.WriteLine("Message : " + e.Message);
}

[C++]
try {
IPHostEntry* hostInfo = Dns::GetHostByName(hostName);
// Get the IP address list that resolves to the host names contained in the
// Alias property.
IPAddress* address[] = hostInfo->AddressList;
// Get the alias names of the addresses in the IP address list.
String* alias[] = hostInfo->Aliases;

Console::WriteLine(S"Host name : {0}", hostInfo->HostName);
Console::WriteLine(S"\nAliases : ");
for (int index=0; index < alias->Length; index++)
Console::WriteLine(alias->Item[index]);

Console::WriteLine(S"\nIP address list : ");
for (int index=0; index < address->Length; index++)
Console::WriteLine(address->Item[index]);

} catch (SocketException* e) {
Console::WriteLine(S"SocketException caught!!!");
Console::WriteLine(S"Source : {0}", e->Source);
Console::WriteLine(S"Message : {0}", e->Message);
} catch (ArgumentNullException* e) {
Console::WriteLine(S"ArgumentNullException caught!!!");
Console::WriteLine(S"Source : {0}", e->Source);
Console::WriteLine(S"Message : {0}", e->Message);
} catch (Exception* e) {
Console::WriteLine(S"Exception caught!!!");
Console::WriteLine(S"Source : {0}", e->Source);
Console::WriteLine(S"Message : {0}", e->Message);
}

[JScript] Для JScript примеры отсутствуют. Для просмотра примера Visual Basic, C# или C++ нажмите кнопку «Язык» в левом верхнем углу страницы.

Требования
Платформы: Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, Семейство Windows Server 2003, .NET Compact Framework - Windows CE .NET, Common Language Infrastructure (CLI) Standard

Безопасность .NET Framework:

DnsPermission на доступ к DNS. Связанное перечисление: PermissionState.Unrestricted

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 15.03.2006 (Ср) 18:26

К модераторам. Есть предложение топик закрыть. Ибо ошибка найдена, да и DNS существует в природе
Весь мир матрица, а мы в нем потоки байтов!


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 101

    TopList