EchoServer设计到实现(一)

背景

作为一个go语言的初学者,EchoServer项目可以让我练手,写了一周多,基本雏形写完了。

因为发现Golang这一块资料挺少的,接下来我会在博客里,总结一下项目最初设计到现在每个阶段怎么做的,怎么制定的。还有遇到的坑都记录下来。

EchoServer初涉

项目主要是网络通信,所以我先写了一个基于C/S的简单的交互,目的熟悉网络基本通信模型,代码如下

server:

 1 package main
  2
  3 import (
  4     "fmt"
  5     "net"
  6     "os"
  7 )
  8
  9 func main() {
 10     listen, err := net.Listen("tcp", "127.0.0.1:12345")
 11     CheckError(err)
 12     defer listen.Close()
 13
 14     for {
 15         conn, err := listen.Accept()
 16         CheckError(err)
 17
 18         fmt.Println("Accept a connet %s", conn.RemoteAddr().String())
 19         go Handle(conn)
 20     }
 21 }
 22 func Handle(conn net.Conn) {
 23     buffer := make([]byte, 1024)
 24      defer conn.Close()
 25     for {
 26         n, err := conn.Read(buffer)
 27         CheckError(err)
 28         fmt.Println("server recv : %n = %s", n, string(buffer))
 29         n, err = conn.Write(buffer[:n])
 30         CheckError(err)
 31     }
 32 }
 33
 34 func CheckError(err error) {
 35     if err != nil {
 36         fmt.Fprintln(os.Stderr, "Error:", err.Error())
 37         os.Exit(1)
 38     }
 39 }

client:

  1 package main
  2
  3 import (
  4     "fmt"
  5     "net"
  6     "os"
  7 )
  8
  9 func main() {
 10     conn,err := net.Dial("tcp","127.0.0.1:12345")
 11     CheckError(err)
 12     defer conn.Close()
 13     buf := make([]byte, 1024)
 14     for {
 15         n, err := conn.Write([]byte("Hello world"))
 16         CheckError(err)
 17         n, err = conn.Read(buf)
 18         CheckError(err)
 19         fmt.Println("recv : %d = %s", n, string(buf))
 20     }
 21 }
 22 func CheckError(err error){
 23     if err != nil{
 24         fmt.Fprintf(os.Stderr, "Error: %s", err.Error())
 25         os.Exit(1)
 26     }
 27 }

运行结果:

![运行结果](/Users/yidwang/Library/Containers/com.tencent.qq/Data/Library/Application\ Support/QQ/Users/1520990951/QQ/Temp.db/1.png)

从server代码中可以看到go的服务端模型没有像C/C++模型中需要socked,bing,listen,write,recv等操作。只需要listen,accept,然后你就可以处理数据了。

在client端设计更为简单,直接Dial启动监听连接就可以通信了。但是跟其他语言下一样,针对client端有多实现方式。我只提供一种简单的实现。

现在C/S中实现的问题

1.仅仅支持发送/接收模式,不支持读写异步。
2.存在接收乱码情况:如果发送频率大于接受频率,接收端会出现毡包情况。
3.文件中存在硬编码问题。
4.每次把错误日志打印到屏幕太粗暴。
5.不支持客户端被动断开和心跳包。
6.一个出问题后,导致服务全部退出

先抛出这些问题,稍后的日志中我会慢慢讲解我是如何解决这些问题的。

你可能感兴趣的:(走在go的路上)