我自己优化了一把,异步的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:%s\n", err.Error())
return
}
_, err = c.Write([]byte(line))
if err != nil {
fmt.Printf("Failure to write: %s\n", 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: %s\n", err.Error())
}
for {
if c, err := l.Accept(); err == nil {
go Echo(c) //new thread
}
}
}
//client.go
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:%s\n", 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:%s\n", s)
}
}
}