傳統編程語言的Socket設計流程:
1.創建socket:socekt();
2.綁定socekt:bind();
3.監聽:listen();
4.連接:connect();
5.接受:accept();
6.接受:receive();
7.發送:send();
但Go語言標準對這些複雜的過程進行抽象封裝,濃縮成簡單的 net.Dial() 調用即可實現;
//Dial()原型
func Dial(net, addr string) (Conn, error)
//常見協議調用方式
conn,err:=net.Dial("tcp","127.0.0.1:7777") //tcp鏈接
conn,err:=net.Dial("udp","127.0.0.1:8888") //udp鏈接
conn,err:=net.Dial("ip4:icmp","www.baidu.com") //ICMP鏈接(使用協議名稱)
conn,err:=net.Dial("ip:1","10.0.0.3") //ICMP鏈接(使用協議編號)
//Dial()目前支持的網絡協議列表
tcp
tcp4 //僅限IPv4
tcp6 //僅限IPv6
udp
udp4 //僅限IPv4
udp6 //僅限IPv6
ip
ip4 //僅限IPv4
ip6 //僅限IPv6
簡單的TCP示例代碼,可運行,只要相應修改 main 中的 service變量即可;
package main
import (
"fmt"
"os"
"io"
"bytes"
"net"
)
// 演示tcp鏈接建立、寫入請求、讀出返回數據的過程
func main(){
fmt.Println("starting")
service := "www.baidu.com:80"
conn,err := net.Dial("tcp", service)
checkError(err)
_,err = conn.Write([]byte("HEAD / HTTP/1.0\r\n\r\n"))
checkError(err)
result, err := readFully(conn)
checkError(err)
fmt.Println(string(result))
os.Exit(0)
}
func checkError(err error) {
if err != nil {
fmt.Println(os.Stderr, "Fatal error: %s", err.Error())
os.Exit(1)
}
}
func readFully(conn net.Conn)([]byte, error){
defer conn.Close()
result := bytes.NewBuffer(nil)
var buf [512]byte
for{
n,err := conn.Read(buf[0:])
result.Write(buf[0:n])
if err != nil {
if err == io.EOF {
break
}
return nil ,err
}
}
return result.Bytes(), nil
}
實際上Dial()函數是對 DialTCP()/DialUDP()/DialIP()/DialUnix()的封裝,外面也可以直接調用這些函數
//原型
func DialTCP(net string, laddr, raddr * TCPAddr)(c *TCPConn, err error)
func DialUDP(net string, laddr, raddr * UDPAddr)(c *TCPConn, err error)
func DialIP(netProto string, laddr, raddr * IPAddr)(c *TCPConn, err error)
func DialUnix(net string, laddr, raddr * UnixAddr)(c *TCPConn, err error)