func main() { l, err := net.Listen("tcp4", ":8080") if err != nil { return } for { c, err := l.Accept() if err != nil { break } fmt.Println("accept connect: ", c.RemoteAddr()) } }
客户端通过 Dial 连接服务端
func main() { c, err := net.DialTimeout("tcp4", "127.0.0.1:8080", time.Second*time.Duration(8)) if err != nil { return } fmt.Println("connect with: ", c.LocalAddr()) }
func Read(b []byte) (n int, err error) func Write(b []byte) (n int, err error)
一般连接建立后,每个连接分别创建读和写两个 go rountine 进行读循环和写循环。
func (c *Conn) open() { go c.readLoop() go c.writeLoop() }
虽然go底层是基于epoll边缘触发,但是并没有暴露接口通知什么时候有可读数据、可写等。为了避免轮询,一般在 go rountine 里阻塞的读、写。由于net.Conn只提供 Close() error,没办法只停止读,等待写结束再关闭连接。一般读做超时处理,超时后如果有关闭标记,则不再尝试读。
func SetReadDeadline(t time.Time) error
连接层需要通知使用者连接的状态,所以引入连接监听 interface
type ConnListener interface { OnConnOpen(c net.Conn) error OnConnClose(c net.Conn) error OnConnError(c net.Conn, err error) OnConnRead(c net.Conn) error OnConnWrite(c net.Conn) error }
使用者只需要实现自己的监听者监听连接的各个生命周期,由读写的 go rountine 驱动业务逻辑执行。
type P2pEnd struct { EndType uint8 EndNo uint16 QueWritePacks chan *P2pPack }
2、P2pPack定义包信息,包括源类型、编号,目标类型、编号,数据,这有利于包的路由。除此以外还有一些控制信息做更精细的处理。
type P2pPack struct { SrcEnd uint8 SrcNo uint16 DstEnd uint8 DstNo uint16 Payload []byte }
这里的包格式是通用包格式,Payload里包含业务包包头,根据业务需求定义自己的包格式。
3、P2pNet是一个端对端网络,维护该通信端所有的连接。作为一个通信端,它首先有自己的端类型、编号
type P2pNet struct { endType uint8 endNo uint16 }
然后要记录其他端与连接的互相映射
type P2pNet struct { endType uint8 endNo uint16 mapConn2End map[net.Conn]*P2pEnd mapId2Conn map[uint32]net.Conn }
所有连接接收到的包放到一个chan里,方便做分发处理
type P2pNet struct { endType uint8 endNo uint16 mapConn2End map[net.Conn]*P2pEnd mapId2Conn map[uint32]net.Conn queReadPacks chan *ReadPackWrap }
还有一些其他的控制信息。
func (r *P2pNet) Register(dstEnd uint8, dstNo uint16) error
除了注册协议,底层的心跳 ping、pong 也在P2P层处理,还有一些防御相关的处理,对业务层透明。
type P2pListener interface { OnP2pConn(p2p *P2pNet, endType uint8, endNo uint16) OnP2pCall(p2p *P2pNet, pack *P2pPack) OnP2pClose(p2p *P2pNet, endType uint8, endNo uint16) OnP2pError(p2p *P2pNet, err error) }
三、关于防御
原文:https://www.cnblogs.com/niudanshui/p/15303017.html