Golang goroutine和chan 教程03

我加入简书的路程 · · 608 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

之前的教程有一个tcp时间戳服务器,这里会详细的解释一下用到的几个重要的函数。

package main

import (
    "io"
    "log"
    "net"
    "time"
)

func main() {
    listenner,err:=net.Listen("tcp","localhost:8000")
    if err != nil {
        log.Fatal(err)
    }
    for  {
        conn,err := listenner.Accept()
        if err != nil {
            log.Print(err)
            continue
        }
        handleConn(conn)
    }
}

func handleConn(c net.Conn) {
    defer c.Close()
    for{
        _,err:=io.WriteString(c,time.Now().Format("15:04:05\n"))
        if err != nil {
            return
        }
        time.Sleep(1*time.Second)
    }
}

func Listen(network, address string) (Listener, error)

// Listen announces on the local network address.
//
// The network must be "tcp", "tcp4", "tcp6", "unix" or "unixpacket".
//
// For TCP networks, if the host in the address parameter is empty or
// a literal unspecified IP address, Listen listens on all available
// unicast and anycast IP addresses of the local system.
// To only use IPv4, use network "tcp4".
// The address can use a host name, but this is not recommended,
// because it will create a listener for at most one of the host's IP
// addresses.
// If the port in the address parameter is empty or "0", as in
// "127.0.0.1:" or "[::1]:0", a port number is automatically chosen.
// The Addr method of Listener can be used to discover the chosen
// port.
//
// See func Dial for a description of the network and address
// parameters.
func Listen(network, address string) (Listener, error) {
    var lc ListenConfig
    return lc.Listen(context.Background(), network, address)
}

这个函数的作用是:
创建一个服务器
函数一共有两个参数,第一个参数是协议类型network,第二个参数是提供服务的地址address。两个参数的类型都是string。


  • 这个服务器的network字段值只能是:
    | network | 字段解释 |
    | :------------- | :------------- |
    | tcp| 基于tcp的一个web服务器 |
    | tcp4 | Item Two |
    | tcp6 | Item Two |
    | unix | Item Two |
    | unixpacket | Item Two |

  • 对于TCP网络,如果address参数中的主机为空或文本未指定的IP地址,则Listen将侦听本地系统的所有可用单播和任播IP地址。
    要仅使用IPv4,请使用网络“tcp4”。地址可以使用主机名,但不推荐这样做,因为它将为主机的至多一个IP地址创建一个监听器。
    如果address参数中的端口为空或“0”,如“127.0.0.1:”或“[:: 1]:0”,则自动选择端口号。Listener的Addr方法可用于发现所选端口。
listenner,err:=net.Listen("tcp","localhost:8000")

总结:listen函数建立了一个tcp服务器,并向外发射tcp服务。产生了两个参数,一个是listenner 一个是err。记得要进行错误处理哦。

listenner 我们所创建的tcp服务器

//一个listenner是自动的网络流处理监听协议
//
// Multiple goroutines may invoke methods on a Listener simultaneously.
type Listener interface {
    // Accept waits for and returns the next connection to the listener.
    Accept() (Conn, error)

    // Close closes the listener.
    // Any blocked Accept operations will be unblocked and return errors.
    Close() error

    // Addr returns the listener's network address.
    Addr() Addr
}

Accept()

// Accept waits for and returns the next connection to the listener.

type Conn interface

// Conn is a generic stream-oriented network connection.
//
// Multiple goroutines may invoke methods on a Conn simultaneously.
type Conn interface {
    // Read reads data from the connection.
    // Read can be made to time out and return an Error with Timeout() == true
    // after a fixed time limit; see SetDeadline and SetReadDeadline.
    Read(b []byte) (n int, err error)

    // Write writes data to the connection.
    // Write can be made to time out and return an Error with Timeout() == true
    // after a fixed time limit; see SetDeadline and SetWriteDeadline.
    Write(b []byte) (n int, err error)

    // Close closes the connection.
    // Any blocked Read or Write operations will be unblocked and return errors.
    Close() error

    // LocalAddr returns the local network address.
    LocalAddr() Addr

    // RemoteAddr returns the remote network address.
    RemoteAddr() Addr

    // SetDeadline sets the read and write deadlines associated
    // with the connection. It is equivalent to calling both
    // SetReadDeadline and SetWriteDeadline.
    //
    // A deadline is an absolute time after which I/O operations
    // fail with a timeout (see type Error) instead of
    // blocking. The deadline applies to all future and pending
    // I/O, not just the immediately following call to Read or
    // Write. After a deadline has been exceeded, the connection
    // can be refreshed by setting a deadline in the future.
    //
    // An idle timeout can be implemented by repeatedly extending
    // the deadline after successful Read or Write calls.
    //
    // A zero value for t means I/O operations will not time out.
    SetDeadline(t time.Time) error

    // SetReadDeadline sets the deadline for future Read calls
    // and any currently-blocked Read call.
    // A zero value for t means Read will not time out.
    SetReadDeadline(t time.Time) error

    // SetWriteDeadline sets the deadline for future Write calls
    // and any currently-blocked Write call.
    // Even if write times out, it may return n > 0, indicating that
    // some of the data was successfully written.
    // A zero value for t means Write will not time out.
    SetWriteDeadline(t time.Time) error
}

最后,产生函数获得接口类型的变量,并输出了时间。


分析

其实listenner是一个抽象的tcp服务器。listenner.Accept()函数返回了一个连接。我们设计了一个永远都不会中断的for循环,不断的调用handleConn(conn)函数,不断的更新一个tcp连接下的值(每隔一秒)。接下来我们要使用go关键字来并发这个服务。


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:我加入简书的路程

查看原文:Golang goroutine和chan 教程03

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

608 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传