TCP 服务器
package mainimport ("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 mainimport ("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 mainimport "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 mainimport ("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 mainimport ("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)}

