Go 语言实现时钟服务器

使用 net 包构建时钟服务器。

时钟服务器

构建一个时钟服务器,每秒一次向客户端发送时间。

package main

import (
    "io"
    "log"
    "net"
    "time"
)

func main() {
    listener, err := net.Listen("tcp", "localhost:8000")
    if err != nil {
        log.Fatal(err)
    }
    for {
        conn, err := listener.Accept()
        if err != nil {
            log.Print(err)
            continue
        }
        handleConn(conn)
    }
}

func handleConn(conn net.Conn) {
    defer conn.Close()
    for {
        _, err := io.WriteString(conn, time.Now().Format("2006-01-02 15:04:05\r\n"))
        if err != nil {
            return
        }
        time.Sleep(1 * time.Second)
    }
}

Listen 函数创建一个 net.Listener 对象,它在一个网络端口上监听进来的连接,这里是 TCP 端口 localhost:8000。监听器的 Accept 方法被阻塞,知道有连接请求进来,然后返回 net.Conn 对象来代表一个连接。

handleConn 函数处理一个完整的客户端连接。在循环里,它将 time.Now() 获取的当前时间发送给客户端。因为 net.Conn 满足 io.Writer 接口,所以可以直接向它进行写入。当写入失败时循环结束,很多时候是客户端断开连接,这是 handleConn 函数使用延迟(defer)的 Close 调用关闭自己这边的连接,然后继续等待下一个连接请求。

使用 telnet 验证时钟服务器。

telnet lcoahost 8000
clock-server1.png

客户端

客户端使用 net.Dial 实现了 Go 版本的 netcat 程序,用来连接 TCP服务器。

package main

import (
    "io"
    "log"
    "net"
    "os"
)

func main() {
    conn, err := net.Dial("tcp", "localhost:8000")
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()
    mustCopy(os.Stdout, conn)
}

func mustCopy(dst io.Writer, src io.Reader) {
    if _, err := io.Copy(dst, src); err != nil {
        log.Fatal(err)
    }
}

支持并发的服务器

如果打开多个客户端,同时只有一个客户端能正常工作。第二个客户端必须等到第一个结束才能正常工作,这是因为服务器是顺序的,一次只能处理一个客户请求。让服务器支持并发需要在调用 handleConn 的地方添加一个 go 关键字,使它在自己的 goroutine 内执行。

for {
        conn, err := listener.Accept()
        if err != nil {
            log.Print(err)
            continue
        }
        go handleConn(conn) // 并发处理连接
}

你可能感兴趣的:(Go 语言实现时钟服务器)