Go 網絡編程:Socket編程

傳統編程語言的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)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章