使用Golang语言编写echo程序
时间:2022-05-05
本文章向大家介绍使用Golang语言编写echo程序,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
网络教程的echo程序,在server断开链接的时候,会出现卡死的情况,如何防止这样的问题出现呢?
我自己优化了一把,异步的echo程序,在client端进行容错判断,在server重启的时候能够进行重新链接。
啥也不说了,上代码。
//server.go
package main
import (
"bufio"
"fmt"
"net"
)
func Echo(c net.Conn) {
defer c.Close()
for {
line, err := bufio.NewReader(c).ReadString('n')
if err != nil {
fmt.Printf("Failure to read:%sn", err.Error())
return
}
_, err = c.Write([]byte(line))
if err != nil {
fmt.Printf("Failure to write: %sn", err.Error())
return
}
}
}
func main() {
fmt.Printf("Server is ready...n")
l, err := net.Listen("tcp", ":8053")
if err != nil {
fmt.Printf("Failure to listen: %sn", err.Error())
}
for {
if c, err := l.Accept(); err == nil {
go Echo(c) //new thread
}
}
}
//client.go
package main
import (
"bufio"
"fmt"
"net"
"os"
"time"
)
type Clienter struct {
client net.Conn
isAlive bool
SendStr chan string
RecvStr chan string
}
func (c *Clienter) Connect() bool {
if c.isAlive {
return true
} else {
var err error
c.client, err = net.Dial("tcp", "127.0.0.1:8053")
if err != nil {
fmt.Printf("Failure to connet:%sn", err.Error())
return false
}
c.isAlive = true
}
return true
}
func (c *Clienter) Echo() {
line := <-c.SendStr
c.client.Write([]byte(line))
buf := make([]byte, 1024)
n, err := c.client.Read(buf)
if err != nil {
c.RecvStr <- string("Server close...")
c.client.Close()
c.isAlive = false
return
}
time.Sleep(1 * time.Second)
c.RecvStr <- string(buf[0:n])
}
func Work(tc *Clienter) {
if !tc.isAlive {
if tc.Connect() {
tc.Echo()
} else {
<-tc.SendStr
tc.RecvStr <- string("Server close...")
}
} else {
tc.Echo()
}
}
func main() {
//defer client.Close()
var tc Clienter
tc.SendStr = make(chan string)
tc.RecvStr = make(chan string)
if !tc.Connect() {
return
}
r := bufio.NewReader(os.Stdin)
for {
switch line, ok := r.ReadString('n'); true {
case ok != nil:
fmt.Printf("bye bye!n")
return
default:
go Work(&tc)
tc.SendStr <- line
s := <-tc.RecvStr
fmt.Printf("back:%sn", s)
}
}
}
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- VM虚拟机中linux centOS 联网单网卡配置教程
- Python操作redis数据库
- pytest 测试框架学习(1):初识
- 爬虫工程师也应该会的 NodeJS 知识(三)- 快速抛弃 execjs
- 八皇后问题Python实现
- 进击吧!Pythonista(6/100)
- 进击吧!Pythonista(9/100)
- 数据结构基础(一)数组,矩阵
- pytest 测试框架学习(3):pytest.approx
- pytest 测试框架学习(4):pytest.fail
- SpringBoot 开发秘籍 - 启动时配置校验
- pytest 测试框架学习(5):pytest.skip
- pytest 测试框架学习(6):pytest.importorskip
- Java 自定义注解及使用场景
- pytest 测试框架学习(8):pytest.exit