使用指定的以太网ip发出http请求

时间:2015-09-11 08:04:21

标签: go

我的计算机上有几个公共IP地址。我想指定哪一个用于请求。

我可以使用curl:

curl --interface 111.222.333.444 https://www.iplocation.net/find-ip-address | grep "Your IP address"

其中111.222.333.444是我用于向互联网发出请求的本地IP地址之一。

如何使用golang进行相同操作?

This方法......

package main

import (
    "bytes"
    "fmt"
    "github.com/PuerkitoBio/goquery"
    "io/ioutil"
    "net"
    "net/http"
    "os"
    "time"
)

func main() {
    var localAddr = "111.222.333.444"
    localAddress, _ := net.ResolveTCPAddr("tcp", localAddr)

    // Create a transport like http.DefaultTransport, but with a specified localAddr
    transport := &http.Transport{
        Proxy: http.ProxyFromEnvironment,
        Dial: (&net.Dialer{
            Timeout:   30 * time.Second,
            KeepAlive: 30 * time.Second,
            LocalAddr: localAddress,
        }).Dial,
        TLSHandshakeTimeout: 10 * time.Second,
    }

    client := &http.Client{
        Transport: transport,
    }

    response, err := client.Get("https://www.whatismyip.com/")

    if err != nil {
        fmt.Printf("%s", err)
        os.Exit(1)
    } else {
        defer response.Body.Close()
        contents, err := ioutil.ReadAll(response.Body)
        if err != nil {
            fmt.Printf("%s", err)
            os.Exit(1)
        }
        var contentsStr = string(contents)
        fmt.Printf("%s\n", contentsStr)
        var doc = DocByHtmlString(contentsStr)

        doc.Find("div").Each(func(i int, s *goquery.Selection) {
            attr, exists := s.Attr("class")
            if exists {
                if attr == "ip" {
                    fmt.Println(s.Text())
                    fmt.Println("expected ip is " + localAddr)
                }
            }
        })
    }
}

func DocByHtmlString(html string) *goquery.Document {
    doc, err := goquery.NewDocumentFromReader(bytes.NewBufferString(html))
    if err != nil {
        panic(err)
    }
    return doc
}

...总是给我以下结果:

Your IP Address Is: 555.666.777.888 // main IP address on my machine
expected ip is 111.222.333.444

Another方法

package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "net"
)

func main() {
    ief, err := net.InterfaceByName("eth0")
    if err != nil {
        log.Fatal(err)
    }
    addrs, err := ief.Addrs()
    if err != nil {
        log.Fatal(err)
    }
    tcpAddr := &net.TCPAddr{
        IP: addrs[3].(*net.IPNet).IP,
        // Port: 8080,
    }
    d := net.Dialer{LocalAddr: tcpAddr}
    conn, err2 := d.Dial("tcp", "www.whatismyip.com:80")
    if err2 != nil {
        log.Fatal(err2)
    }
    fmt.Println(`conn.LocalAddr()`)
    fmt.Println(conn.LocalAddr())
    fmt.Println(`conn.RemoteAddr()`)
    fmt.Println(conn.RemoteAddr())
    defer conn.Close()
    bytesResult, err3 := ioutil.ReadAll(conn)
    if err3 != nil {
        log.Fatal(err3)
    }
    fmt.Println(`string(bytesResult)`)
    fmt.Println(string(bytesResult))
}

给出输出

conn.LocalAddr()
111.222.333.213:37036 
conn.RemoteAddr()
141.101.120.15:80
                     // 15 seconds pause
string(bytesResult)
                     // empty string

ifcongif

Ubuntu 14.04.3 LTS(GNU / Linux 3.13.0-63-generic x86_64)

$ ifconfig
eth0      Link encap:Ethernet  HWaddr 00:18:3c:96:69:8c  
          inet addr:111.222.333.208  Bcast:111.222.333.255  Mask:255.255.255.0
          inet6 addr: de90::216:3cff:fe56:698c/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:942000 errors:0 dropped:0 overruns:0 frame:0
          TX packets:336708 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:133860794 (133.8 MB)  TX bytes:84577381 (84.5 MB)

eth0:0    Link encap:Ethernet  HWaddr 00:18:3c:96:69:8c  
          inet addr:111.222.333.209  Bcast:111.222.333.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

eth0:1    Link encap:Ethernet  HWaddr 00:18:3c:96:69:8c  
          inet addr:111.222.333.212  Bcast:111.222.333.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

eth0:2    Link encap:Ethernet  HWaddr 00:18:3c:96:69:8c  
          inet addr:111.222.333.213  Bcast:111.222.333.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

eth0:3    Link encap:Ethernet  HWaddr 00:18:3c:96:69:8c  
          inet addr:111.222.333.216  Bcast:111.222.333.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

eth0:4    Link encap:Ethernet  HWaddr 00:18:3c:96:69:8c  
          inet addr:111.222.333.217  Bcast:111.222.333.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

eth0:5    Link encap:Ethernet  HWaddr 00:18:3c:96:69:8c  
          inet addr:111.222.333.220  Bcast:111.222.333.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

eth0:6    Link encap:Ethernet  HWaddr 00:18:3c:96:69:8c  
          inet addr:111.222.333.221  Bcast:111.222.333.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

eth0:7    Link encap:Ethernet  HWaddr 00:18:3c:96:69:8c  
          inet addr:111.222.333.224  Bcast:111.222.333.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

eth0:8    Link encap:Ethernet  HWaddr 00:18:3c:96:69:8c  
          inet addr:111.222.333.225  Bcast:111.222.333.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

1 个答案:

答案 0 :(得分:3)

谢谢@JimB。工作解决方案:

package main

import (
    "bytes"
    "fmt"
    "github.com/PuerkitoBio/goquery"
    "io/ioutil"
    "log"
    "net"
    "net/http"
    "os"
    "time"
)

func main() {
    ief, err := net.InterfaceByName("eth0")
    if err != nil {
        log.Fatal(err)
    }
    addrs, err := ief.Addrs()
    if err != nil {
        log.Fatal(err)
    }
    tcpAddr := &net.TCPAddr{
        IP: addrs[3].(*net.IPNet).IP, // Choosing ip address number 3
    }
    d := net.Dialer{LocalAddr: tcpAddr}
    conn, err2 := d.Dial("tcp", "www.whatismyip.com:80")
    if err2 != nil {
        log.Fatal(err2)
    }
    fmt.Println(`conn.LocalAddr()`)
    fmt.Println(conn.LocalAddr())
    fmt.Println(`conn.RemoteAddr()`)
    fmt.Println(conn.RemoteAddr())
    defer conn.Close()

    transport := &http.Transport{
        Proxy:               http.ProxyFromEnvironment,
        Dial:                (&net.Dialer{LocalAddr: tcpAddr}).Dial,
        TLSHandshakeTimeout: 10 * time.Second,
    }

    client := &http.Client{
        Transport: transport,
    }

    response, err := client.Get("https://www.whatismyip.com/")

    if err != nil {
        fmt.Printf("%s", err)
        os.Exit(1)
    } else {
        defer response.Body.Close()
        contents, err := ioutil.ReadAll(response.Body)
        if err != nil {
            fmt.Printf("%s", err)
            os.Exit(1)
        }
        var contentsStr = string(contents)
        fmt.Printf("%s\n", contentsStr)
        var doc = DocByHtmlString(contentsStr)

        doc.Find("div").Each(func(i int, s *goquery.Selection) {
            attr, exists := s.Attr("class")
            if exists {
                if attr == "ip" {
                    fmt.Println(s.Text())
                }
            }
        })
    }
}

func DocByHtmlString(html string) *goquery.Document {
    doc, err := goquery.NewDocumentFromReader(bytes.NewBufferString(html))
    if err != nil {
        panic(err)
    }
    return doc
}

按预期在最后Your IP Address Is: 111.222.333.213打印。