[日常] 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, "\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服务的更多相关文章
- [日常] Go语言圣经--示例: 并发的Clock服务习题
练习 8.1: 修改clock2来支持传入参数作为端口号,然后写一个clockwall的程序,这个程序可以同时与多个clock服务器通信,从多服务器中读取时间,并且在一个表格中一次显示所有服务传回的结 ...
- [日常] Go语言圣经-示例: 并发的目录遍历习题
练习 8.9: 编写一个du工具,每隔一段时间将root目录下的目录大小计算并显示出来. package main import ( // "filepath" "fla ...
- [日常] GO语言圣经-并发获取多个URL
go语言圣经-并发获取多个URL 1.GO最新奇的特性就是对并发编程的支持,goroutine和channel 2.goroutine是一种函数的并发执行方式,而channel是用来在goroutin ...
- [日常] Go语言圣经-WEB服务与习题
Go语言圣经-web服务 1.Web服务程序,标准库里的方法已经帮我们完成了大量工作 2.main函数将所有发送到/路径下的请求和handler函数关联起来,/开头的请求其实就是所有发送到当前站点上的 ...
- [日常] Go语言圣经前言
https://books.studygolang.com/gopl-zh/ go语言圣经 1.Go语言有时候被描述为“C类似语言”,或者是“21世纪的C语言”. 2.Go语言中和并发编程相关的特性是 ...
- [日常] Go语言圣经--接口约定习题
Go语言圣经-接口1.接口类型是对其它类型行为的抽象和概括2.Go语言中接口类型的独特之处在于它是满足隐式实现的3.Go语言中还存在着另外一种类型:接口类型.接口类型是一种抽象的类型4.一个类型可以自 ...
- [日常] Go语言圣经-Panic异常,Recover捕获异常习题
Go语言圣经-Panic异常1.当panic异常发生时,程序会中断运行,并立即执行在该goroutine中被延迟的函数(defer 机制)2.不是所有的panic异常都来自运行时,直接调用内置的pan ...
- [日常] Go语言圣经-匿名函数习题
Go语言圣经-匿名函数1.拥有函数名的函数只能在包级语法块中被声明,通过函数字面量(function literal),我们可绕过这一限制,在任何表达式中表示一个函数值2.通过这种方式定义的函数可以访 ...
- [日常] Go语言圣经-错误,函数值习题
Go语言圣经-错误 1.panic异常.panic是来自被调函数的信号,表示发生了某个已知的bug 2.任何进行I/O操作的函数都会面临出现错误的可能 3.错误是软件包API和应用程序用户界面的一个重 ...
随机推荐
- 开发 C# OPC 客户端
编写 opc 客户端的思路 1. 使用OPC Client浏览服务器, 查看测试代码修改后的结果. 2. 根据OPC Client搜集到的服务器信息编写代码和服务器交互 3. OPC Client 操 ...
- WPF Command CanExecute 触发一次的问题
昨天在项目中遇到一个问题,按钮bind了Command后,利用CanExecute控制它的是否可点击.结果却在初始化viewmodel的时候执行了一次CanExecute,之后一直不触发,按钮的可用性 ...
- Flask系列05--Flask的配置config
一.flask配置 示例说明, 就是使用config进行配置 from flask import Flask app = Flask(__name__) # type:Flask app.conf ...
- 不同的最小割(cqoi2016,bzoj4519)(最小割树)
学过图论的同学都知道最小割的概念:对于一个图,某个对图中结点的划分将图中所有结点分成 两个部分,如果结点\(s,t\)不在同一个部分中,则称这个划分是关于\(s,t\)的割.对于带权图来说,将 所有顶 ...
- [NOIP2018]赛道修建(二分+multiset)
考场上打了一个 \(vector\) 解法,因为我当时不会 \(multiset\) 好吧,我来讲一讲今年的 \(tgD1T3\) 首先,这题 \(55\) 分是不难想的 1. \(b_i=a_i+1 ...
- 前端基础-html 列表标签,表格标签,表单标签
一.列表标签 1.ul(无序列表)标签 ul(unordered list)无序列表,ul下的子元素只能是li(list item),如下示例: <ul> <li>第一项< ...
- cas未能够识别出目标 ***;票根
使用cas做单点登录,在验证ticket的时候,报下面的错误: <cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'> & ...
- pika配置文件说明
# Pika 端口 port : 9221 # pika进程数量,不建议超过核心数量,pika是多线程的 thread-num : 1 # Sync 线程数量 sync-thread-num : 6 ...
- Linux的基本操作
1.linux系统的基本命令 ls 查看当前所在文夹下的内容pwd 查看当前所在的位置cd 打开文件目录touch 创建文件, 如果文件不存在, 就创建新的文件mkdir 创建文件夹rm 删 ...
- jquery中ajax的几种方式
三种简写: $.get(URL,data,function(data,status,xhr),dataType) $(selector).post(URL,data,function(data,sta ...