zoukankan      html  css  js  c++  java
  • [日常] Go语言*--示例: 并发的Echo服务

    最简单的回声服务器:

    package main
    
    import (
            "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 main
    
    import (
            "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, "	", strings.ToUpper(shout))
            time.Sleep(delay)
            fmt.Fprintln(c, "	", shout)
            time.Sleep(delay)
            fmt.Fprintln(c, "	", 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节 实现接口的条件

      

  • 相关阅读:
    Xdebug
    单点登录
    一个Https网站发送Http的 ajax请求的解决方法
    js关闭微信浏览器页面
    标准的身份证验证(第18位校验码)
    Redis 更新(set) key值 会重置过期时间问题
    PHP 报错:Deprecated: Methods with the same name as their class will not be constructor...
    php防sql注入
    web开发原则
    fopen()函数
  • 原文地址:https://www.cnblogs.com/taoshihan/p/8964902.html
Copyright © 2011-2022 走看看