標籤:fun handle 類型 hand alt pre from int can
最簡單的回聲伺服器:
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.Reader
type 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節 實現介面的條件
[日常] Go語言聖經--樣本: 並發的Echo服務