Go 网络编程简介

TCP 服务器

package main

import (
    "fmt"
    "log"
    "net"
)

func main() {
    // net 包提供方便的工具用于 network I/O 开发,包括TCP/IP, UDP 协议等。
    // Listen 函数会监听来自 8080 端口的连接,返回一个 net.Listener 对象。
    li, err := net.Listen("tcp", ":8080")
    // 错误处理
    if err != nil {
        log.Panic(err)
    }
    // 释放连接,通过 defer 关键字可以让连接在函数结束前进行释放
    // 这样可以不关心释放资源的语句位置,增加代码可读性
    defer li.Close()

    // 不断循环,不断接收来自客户端的请求
    for {
        // Accept 函数会阻塞程序,直到接收到来自端口的连接
        // 每接收到一个链接,就会返回一个 net.Conn 对象表示这个连接
        conn, err := li.Accept()

        if err != nil {
            log.Println(err)
        }
        // 字符串写入到客户端
        fmt.Fprintln(conn, "Hello from TCP server")

        conn.Close()
    }
}


TCP 客户端

package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "net"
)

func main() {
    // net 包的 Dial 函数能创建一个 TCP 连接
    conn, err := net.Dial("tcp", ":8080")
    if err != nil {
        log.Fatal(err)
    }
    // 别忘了关闭连接
    defer conn.Close()
    // 通过 ioutil 来读取连接中的内容,返回一个 []byte 类型的对象
    byte, err := ioutil.ReadAll(conn)
    if err != nil {
        log.Println(err)
    }
    // []byte 类型的数据转成字符串型,再将其打印输出
    fmt.Println(string(byte))
}

HTTP服务器

 

 

package main

import "net/http"

func main() {
    http.ListenAndServe(":8080", nil)
}

   Go 是通过一个函数 ListenAndServe 来处理这些事情的,这个底层其实这样处理的:初始化一个server 对象,然后调用了 net.Listen("tcp", addr),也就是底层用 TCP 协议搭建了一个服务,然后监控我们设置的端口。

 

 

     查文档可以发现 http 包下的 ListenAndServe 函数第一个参数是地址,而第二个是 Handler 类型的参数,我们想要显示内容就要在第二个参数下功夫。

func ListenAndServe(addr string, handler Handler) error

  再次查文档,得知 Handler 是一个接口,也就是说只要我们给某一个类型创建 ServeHTTP(ResponseWriter, *Request) 方法,就能符合接口的要求,也就实现了接口。

 

HandleFun

package main

import (
    "fmt"
    "net/http"
)

func boy(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "I love you!!!")
}

func girl(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "hehe.")
}

func foo(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "Men would stop talking and women would shed tears when they see this.")
}

func main() {
    http.HandleFunc("/boy/", boy)
    http.HandleFunc("/girl/", girl)
    http.HandleFunc("/", foo)
    http.ListenAndServe(":8080", nil)
}

HandleFunc

 

 

    http 包里面还定义了一个类型 http.HandlerFunc,该类型默认实现 Handler 接口,我们可以通过 HandlerFunc(foo) 的方式来实现类型强转,使 foo 也实现了 Handler 接口。

package main

import (
    "fmt"
    "net/http"
)

func boy(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "I love you!!!")
}

func girl(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "hehe.")
}

func foo(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "Men would stop talking and women would shed tears when they see this.")
}

func main() {
    // http.Handler() 的第二个参数是要实现了 Handler 接口的类型
    // 可以通过类型强转来重新使用该函数来实现
    http.Handle("/boy/", http.HandlerFunc(boy))
    http.Handle("/girl/", http.HandlerFunc(girl))
    http.Handle("/", http.HandlerFunc(foo))
    http.ListenAndServe(":8080", nil)
}

参考:

https://www.yuque.com/docs/share/fd10d689-9bd9-467b-9f31-f0507e26f52a

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值