传统编程语言的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)