EDIT: I decided to change this post's title, to express the problem I'm actually trying to solve...

As the title (now) says, the problem is in fact clear: I just want to know how to get the IP address of some hostname I have.

I tried using getHostByName() but failed. What I need is either to know how to extract the IpAddress from the getHostByName() output, OR some alternative method of getting the same information, either as a IpAddress, or a string like "".

Here is the original port:

I'm trying to write a (very) primitive "service discovery" module, and it seems "nativesockets.Hostent.addrList" is not what I would have expected.

Here the code I used:

import nativesockets
import net
import strutils

proc parseURL(hostport: string): tuple[ip: string, port: Port, url: string] =
  let idx = hostport.find(':')
  if (idx < 1) or (idx == high(hostport)):
    raise newException(Exception, "Bad URL: '" & hostport & "': port missing")
  let host = hostport.substr(0,idx-1)
  let portstr = hostport.substr(idx+1)
  var port = -1
    port = parseInt(portstr)
  if (port < 1) or (port > 65535):
    raise newException(Exception, "Bad URL: '" & hostport & "': bad port")
  var ip: IpAddress
  if isIpAddress(host):
      ip = parseIpAddress(host)
      raise newException(Exception, "Bad URL: '" & hostport & "': bad IP address")
    var hostent: Hostent
      hostent = getHostByName(host)
      raise newException(Exception, "Bad URL: '" & hostport & "': bad hostname")
    if hostent.addrList.len == 0:
      raise newException(Exception, "Bad URL: '" & hostport & "': no IP for hostname")
    let a = hostent.addrList[0]
      ip = parseIpAddress(a)
      raise newException(Exception, "Bad URL: '" & hostport & "': failed to parse IP of address: " & $len(a) & " " & a)
  result = ($ip, Port(port), hostport)

echo("RESULT: " & $parseURL("google.com:80"))

This fails with the last "raise" line, like this:

testgethostbyname.nim(40) testgethostbyname
testgethostbyname.nim(37) parseURL
Error: unhandled exception: Bad URL: 'google.com:80': failed to parse IP of address: 14 Ï:ð.google.com [Exception]
Error: execution of an external program failed: '../bin/testgethostbyname '

Either there is something terribly wrong with my code, or "hostent.addrList[0]" is not something like "", but something else entirely. In that case, since the type is "string", how am I meant to "interpret" it, to get something like ""? Or is there an alternative call to getHostByName() that actually returns an IP in a "usable format"?

I wanted to use the "ip" to pass it to Socket.connect(ip, port), so I save the DNS query on repeated calls.

2018-02-11 18:31:37

In case anyone cares, this how I eventually did it:

let first = hostent.addrList[0]
let a = uint8(first[0])
let b = uint8(first[1])
let c = uint8(first[2])
let d = uint8(first[3])
let ipstr = $a & "." & $b & "." & $c & "." & $d
  ip = parseIpAddress(ipstr)
  raise newException(Exception, "Bad URL: '" & hostport & "': failed to parse IP of address: " & ipstr)

Rather ugly, but seems to work.

2018-02-18 17:02:59