該模塊相對比較簡單,由於nat的真正實現並不在此模塊,主要是使用了第三方的nat-upnp和nat-pmp來實現真正的穿透(端口映射).app
對外公佈的接口
```go
// An implementation of nat.Interface can map local ports to ports
// accessible from the Internet.
type Interface interface {
// These methods manage a mapping between a port on the local
// machine to a port that can be connected to from the internet.
//
// protocol is "UDP" or "TCP". Some implementations allow setting
// a display name for the mapping. The mapping may be removed by
// the gateway when its lifetime ends.
AddMapping(protocol string, extport, intport int, name string, lifetime time.Duration) error
DeleteMapping(protocol string, extport, intport int) errortcp
// This method should return the external (Internet-facing) // address of the gateway device. ExternalIP() (net.IP, error) // Should return name of the method. This is used for logging. String() string
}
```函數
主要有三個關鍵函數一個是添加映射,一個是刪除映射,另外一個是獲取外部IP.使用起來很是直觀,咱們這裏看一個例子,nat.go中的Map函數中,
m.AddMapping(protocol, extport, intport, name, mapTimeout);
ui
我看ethereum使用的時候,extport和intport都同樣. Interface總共有四個實現分別是upnp,pmp,extIP和startautodisc,從名字能夠看出這四個實現都沒有暴露給調用者,也就是內部使用,其中extIP是在本機IP就是公網IP的狀況下使用,也就是無需端口映射的時候使用.upnp和pmp是對兩種端口映射協議的使用封裝,而startautodisc則是對這二者的再次封裝統一. 那麼nat模塊怎麼使用呢,用起來其實很簡單.下面是示例代碼,不完整.
//獲取nat實例, var m nat.Interface=nat.Any() //而後就能夠使用AddMapping等操做了, //nat還提供了更方便的函數Map來保持端口映射 //用法以下 來自server.go nat.Map(srv.NAT, srv.quit, "tcp", laddr.Port, laddr.Port, "ethereum p2p")