最简单的回声服务器:
package mainimport ( "io" "net" "log")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处理连接 } }func handleConn(c net.Conn) { io.Copy(c, c) // NOTE: ignoring errors c.Close()}
原理:
1.io.Copy()方法
func Copy(dst Writer, src Reader) (written int64, err error)2.net.Conn类型
type Conn interface { Read(b []byte) (n int, err error) Write(b []byte) (n int, err error) ...}一个类型如果拥有一个接口需要的所有方法,那么这个类型就实现了这个接口3.io.Writer
type Writer interface { Write(p []byte) (n int, err error)}4.io.Readertype Reader interface { Read(p []byte) (n int, err error)}升级版,每条连接一个goroutine,每个goroutine中分出多个输出goroutine
package mainimport ( "bufio" "fmt" "log" "net" "strings" "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处理连接 } }func handleConn(c net.Conn) { input := bufio.NewScanner(c) for input.Scan() { go echo(c, input.Text(), 1*time.Second) } // NOTE: ignoring potential errors from input.Err() c.Close()}func echo(c net.Conn, shout string, delay time.Duration) { 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))}
1.fmt.Fprintln()
func Fprintln(w io.Writer, a ...interface{}) (n int, err error)2.bufio.NewScanner()
func NewScanner(r io.Reader) *Scanner func (s *Scanner) Scan() bool func (s *Scanner) Text() string也用到了大量的7.3节 实现接口的条件