Master Go’s net.Dial: From Socket Basics to HTTP Clients

This article explains Go's socket programming workflow, detailing the traditional steps of creating, binding, listening, and communicating over sockets, then shows how net.Dial simplifies connections for TCP, UDP, and ICMP, and demonstrates practical HTTP client usage with code examples.

MaGe Linux Operations
MaGe Linux Operations
MaGe Linux Operations
Master Go’s net.Dial: From Socket Basics to HTTP Clients

Socket Programming

Traditional socket programming steps: create a socket with socket(), bind it with bind(), listen or connect, accept connections, then receive or send data. Go's standard library abstracts this process with net.Dial(), which works for any protocol.

Dial() function

Signature: func Dial(net, addr string) (Conn, error) The net parameter specifies the protocol name, and addr is an IP address or hostname with an optional port (e.g., host:port). On success it returns a connection object; otherwise it returns an error.

Examples:

TCP: conn, err := net.Dial("tcp", "192.168.0.10:2100") UDP: conn, err := net.Dial("udp", "192.168.0.12:975") ICMP: conn, err := net.Dial("ip4:icmp", "www.baidu.com") ICMP (numeric): conn, err := net.Dial("ip4:1", "10.0.0.3") Supported protocols include tcp, tcp4, tcp6, udp, udp4, udp6, ip, ip4, and ip6.

After a connection is established, use conn.Write() to send data and conn.Read() to receive data.

ICMP example program

The following program sends an ICMP echo request to a host and validates the response.

package main
import (
    "net"
    "os"
    "bytes"
    "fmt"
)

func main() {
    if len(os.Args) != 2 {
        fmt.Println("Usage:", os.Args[0], "host")
        os.Exit(1)
    }
    service := os.Args[1]
    conn, err := net.Dial("ip4:icmp", service)
    checkError(err)
    var msg [512]byte
    msg[0] = 8  // echo
    msg[1] = 0  // code 0
    msg[2] = 0  // checksum
    msg[3] = 0  // checksum
    msg[4] = 0  // identifier[0]
    msg[5] = 13 // identifier[1]
    msg[6] = 0  // sequence[0]
    msg[7] = 37 // sequence[1]
    len := 8
    check := checkSum(msg[0:len])
    msg[2] = byte(check >> 8)
    msg[3] = byte(check & 255)
    _, err = conn.Write(msg[0:len])
    checkError(err)
    _, err = conn.Read(msg[0:])
    checkError(err)
    fmt.Println("Got response")
    if msg[5] == 13 {
        fmt.Println("Identifier matches")
    }
    if msg[7] == 37 {
        fmt.Println("Sequence matches")
    }
    os.Exit(0)
}

func checkSum(msg []byte) uint16 {
    sum := 0
    for n := 1; n < len(msg)-1; n += 2 {
        sum += int(msg[n])*256 + int(msg[n+1])
    }
    sum = (sum >> 16) + (sum & 0xffff)
    sum += sum >> 16
    answer := uint16(^sum)
    return answer
}

func checkError(err error) {
    if err != nil {
        fmt.Fprintf(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
}

Running the program produces:

$ go build icmptest.go
$ ./icmptest www.baidu.com
Got response
Identifier matches
Sequence matches

TCP example program

This example establishes a TCP connection, sends an HTTP HEAD request, and prints the server's response.

package main
import (
    "net"
    "os"
    "bytes"
    "fmt"
)

func main() {
    if len(os.Args) != 2 {
        fmt.Fprintf(os.Stderr, "Usage: %s host:port", os.Args[0])
        os.Exit(1)
    }
    service := os.Args[1]
    conn, err := net.Dial("tcp", service)
    checkError(err)
    _, err = conn.Write([]byte("HEAD / HTTP/1.0

"))
    checkError(err)
    result, err := readFully(conn)
    checkError(err)
    fmt.Println(string(result))
    os.Exit(0)
}

func checkError(err error) {
    if err != nil {
        fmt.Fprintf(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
}

Sample execution output:

$ go build simplehttp.go
$ ./simplehttp qbox.me:80
HTTP/1.1 301 Moved Permanently
Server: nginx/1.0.14
Date: Mon, 21 May 2012 03:15:08 GMT
Content-Type: text/html
Content-Length: 184
Connection: close
Location: https://qbox.me/

HTTP Programming

HTTP (HyperText Transfer Protocol) is the most widely used internet protocol, defining request and response standards between clients and servers. Go's standard library provides the net/http package for both client and server implementations.

HTTP client

The net/http package's Client type offers several convenient methods:

func (c *Client) Get(url string) (resp *Response, err error)
func (c *Client) Post(url string, bodyType string, body io.Reader) (resp *Response, err error)
func (c *Client) PostForm(url string, data url.Values) (resp *Response, err error)
func (c *Client) Head(url string) (resp *Response, err error)
func (c *Client) Do(req *Request) (resp *Response, err error)

Examples:

Simple GET: resp, err := http.Get("http://example.com/") POST an image:

resp, err := http.Post("http://example.com/upload", "image/jpeg", &imageDataBuf)

POST a form:

resp, err := http.PostForm("http://example.com/posts", url.Values{"title": {"article title"}, "content": {"article body"}})

HEAD request: resp, err := http.Head("http://example.com/") Custom request with headers:

req, err := http.NewRequest("GET", "http://example.com", nil)
req.Header.Add("User-Agent", "Gobook Custom User-Agent")
client := &http.Client{}
resp, err := client.Do(req)
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

GoHTTPNetwork programmingsocket programmingnet.Dial
MaGe Linux Operations
Written by

MaGe Linux Operations

Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.