閱讀源代碼發現在net包中主要實現了ip、tcp、udp、unix等通信方式。它們大致可以分成兩大類;其一,ip、udp、unix(DGRAM),這是一些無鏈接的協議,其二,tcp、unix(STREAM),需要建立鏈接。net對這兩類協議的使用有一些區別,最明顯的是對於tcp、unix(STEAM)這些協議需要使用一個Listener接口來進行服務端的監聽,
其中每一種通信方式都使用 xxConn 結構體來表示,諸如IPConn、TCPConn等,這些結構體都實現了Conn接口,Conn接口實現了基本的讀、寫、關閉、獲取遠程和本地地址、設置timeout等功能。
1 type Conn interface { 2 3 Read(b []byte) (n int, err error) 4 5 Write(b []byte) (n int, err error) 6 7 Close() error 8 9 LocalAddr() Addr 10 11 RemoteAddr() Addr 12 13 SetDeadline(t time.Time) error 14 15 SetReadDeadline(t time.Time) error 16 17 SetWriteDeadline(t time.Time) error 18 }
1、ip
使用IPConn結構體來表示,它實現了Conn、PacketConn兩種接口。使用如下兩個函數進行Dial和Listen。
func DialIP(netProto string, laddr, raddr *IPAddr) (*IPConn, error) func ListenIP(netProto string, laddr *IPAddr) (*IPConn, error)
2、tcp
使用TCPConn結構體來表示,它實現了Conn接口。
使用DialTCP進行Dial操作:
func DialTCP(net string, laddr, raddr *TCPAddr) (*TCPConn, error)
使用 ListenTCP函數進行Listen,產生一個TCPListener結構體
func ListenTCP(net string, laddr *TCPAddr) (*TCPListener, error)
使用TCPListener的AcceptTCP方法建立通信鏈路,得到TCPConn。
3、udp
使用UDPConn接口體來表示,它實現了Conn、PacketConn兩種接口。使用如下兩個函數進行Dial和Listen。
func DialUDP(net string, laddr, raddr *UDPAddr) (*UDPConn, error) func ListenUDP(net string, laddr *UDPAddr) (*UDPConn, error)
4、unix
UnixConn實現了Conn、PacketConn兩種接口,其中unix又分為SOCK_DGRAM、SOCK_STREAM。
4.1 對於unix(SOCK_DGRAM),使用如下兩個函數進行Dial和Listen。
func DialUnix(net string, laddr, raddr *UnixAddr) (*UnixConn, error) func ListenUnixgram(net string, laddr *UnixAddr) (*UnixConn, error)
4.2 對於unix(SOCK_STREAM)
客戶端使用DialUnix進行Dial操作
func DialUnix(net string, laddr, raddr *UnixAddr) (*UnixConn, error)
服務端使用ListenUnix函數進行Listen操作,然后使用UnixListener進行AcceptUnix
func ListenUnix(net string, laddr *UnixAddr) (*UnixListener, error)
5 為了使用方便,golang將一些重復的操作集中到一個函數中。
可以發現上述幾種通信,都得有Dialxxx、Listenxxx操作,但是根據有無鏈接,有分成了兩大類,其中一種Listenxxx后直接返回對應的xxxConn,另一種Listenxxx后得到xxxListener,還需要借助Accepxxx進行獲取xxxConn。所以為了偷懶,又有如下函數:
func ListenPacket(net, laddr string) (PacketConn, error)
這個函數用於偵聽ip、udp、unix(DGRAM)等協議,返回一個PacketConn接口,同樣根據偵聽的協議不同,這個接口可以包含IPCon、UDPConn、UnixConn等,它們都實現了PacketConn。可以發現與ip、unix(stream)協議不同,直接返回的是xxConn,不是間接的通過Listener進行Accept操作后,才得到一個Conn。
func Listen(net, laddr string) (Listener, error)
這個函數用於偵聽tcp、unix(stream)等協議,返回一個Listener接口、根據偵聽的協議不同,這個接口可以包含TCPListener、UnixListener等,它們都實現了Listener接口,然后通過調用其Accept方法可以得到Conn接口,進行通信。
func Dial(network, address string) (Conn, error)
這個函數對於所有的協議都是相同的操作,返回一個Conn接口,根據協議的不同實際上包含IPConn、UDPConn、UnixConn、IPConn,它們都實現了Conn接口