The Bible of Go language

Exercise 8.4: modify the revb2 server to use sync.WaitGroup in each connection to count the active echo goroutine. When the count is reduced to zero, turn off writing of the TCP connection, as in exercise 8.3. Verify that your modified version of netcat 3 client will always wait for all concurrent "shouts" to complete, even when the standard input stream is closed.

 

Important: wait for all goroutine execution to complete before closing the TCP connection

package main

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

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) //New goroutines processing connection
        }   
}

func handleConn(c net.Conn) {
        input := bufio.NewScanner(c)
        var wg sync.WaitGroup
        //var  ch =make(chan struct{})
        for input.Scan() {
                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, input.Text(), 1*time.Second)
        }   
        wg.Wait()
                //cw := c.(*net.TCPConn)
          //cw.CloseWrite()
        
        c.Close()
}

Tags: Go

Posted on Thu, 26 Mar 2020 08:58:27 -0700 by drewklue