1. 程式人生 > >[日常] Go語言聖經-基於select的多路復用習題

[日常] Go語言聖經-基於select的多路復用習題

string con print text 習題 true ont IT 語句

練習 8.8: 使用select來改造8.3節中的echo服務器,為其增加超時,這樣服務器可以在客戶端10秒中沒有任何喊話時自動斷開連接。

reverb3.go

package main

import (
        "bufio"
        "fmt"
        "log"
        "net"
        "strings"
        "sync"
        "time"
)

func main() {
        listener, err := net.Listen("tcp", ":8040")
        if err != nil {
                log.Fatal(err)
        }

        for {
                conn, err := listener.Accept()
                if err != nil {
                        log.Print(err) // e.g., connection aborted
                        continue
                }
                go handleConn(conn) //新建goroutines處理連接
        }
}
/*
1.啟動一個goroutine,for死循環讓他不能斷掉
select語句case判斷兩個channel
一個是10秒後斷掉連接
另一個是接收標準輸入後發送過來的channel,接收到值後,啟動goroutinue輸出

2.for循環接收標準輸入,接收到後發送給message的channel
*/
func handleConn(c net.Conn) {
        input := bufio.NewScanner(c)
        var wg sync.WaitGroup
        var message = make(chan string)
        wg.Add(1)
        go func() {
                defer wg.Done()
                for {
                        select {
                        case <-time.After(10 * time.Second):
                                c.Close()
                        case mes := <-message:
                                wg.Add(1)
                                go func(c net.Conn, shout string, delay time.Duration) {
                                        defer wg.Done()
                                        fmt.Fprintln(c, "\t", strings.ToUpper(shout))
                                        time.Sleep(delay)
                                        fmt.Fprintln(c, "\t", shout)
                                        time.Sleep(delay)
                                        fmt.Fprintln(c, "\t", strings.ToLower(shout))
                                        //ch<-struct{}{}

                                }(c, mes, 1*time.Second)

                        }
                }
        }()
        for input.Scan() {
                text := input.Text()
                message <- text
        }

        wg.Wait()
        //cw := c.(*net.TCPConn)
        //cw.CloseWrite()

        c.Close()
}

  

[日常] Go語言聖經-基於select的多路復用習題