[Daily] Go Language Bible--Channel Exercises

Exercise 8.3: In the netcat3 example, although conn is a value of interface type, its underlying real type is *net.TCPConn, which represents a TCP connection. A TCP connection has two parts, read and write, which can be closed using the CloseRead and CloseWrite methods, respectively. Modify the main goroutine code of netcat3 to only close the part written in the network connection, so that the background goroutine can continue to print the data returned from the reverb1 server after the standard input is closed. (It is more difficult to do the same on the reverb2 server; see exercise 8.4.)


1.
net.Dial()
func Dial(network, address string) (Conn, error)
2.net.TCPConn
type TCPConn struct {
// contains filtered or unexported fields
}
TCPConn is an implementation of the Conn interface for TCP network connections.

 

package main

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

func main() {
        conn, err := net.Dial("tcp", "localhost:8040")
        if err != nil {
                log.Fatal(err)
        }   
        //The built-in make function creates a channel that can send data of type struct
        done := make(chan struct{})
        //go statement calls a function literal, the usual form of starting a goroutine
        go func() {
                //Connect to standard output from the network, and block if the connection is not broken
                //If the TCP read connection is closed, an error will be reported: use of closed network connection
                _, err := io.Copy(os.Stdout, conn)
                log.Println(err)
                log.Println("done")
                //Send channel to receiving goroutine
                done <- struct{}{}
        }()
        //From the standard input to the network connection, this place will block, press Control+D to close the standard input
        mustCopy(conn, os.Stdin)
        //      conn.Close()
        //Type assertion, calling the *net.TCPConn method CloseWrite() only closes the TCP write connection
        cw := conn.(*net.TCPConn)
        cw.CloseWrite()
        <-done // Block waiting for the background goroutine to finish receiving the channel
}
func mustCopy(dst io.Writer, src io.Reader) {
        if _, err := io.Copy(dst, src); err != nil {
                log.Fatal(err)
        }   
}

  

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325019538&siteId=291194637