blockchain/network/net.go
2020-07-12 01:47:33 -04:00

87 lines
1.6 KiB
Go

package network
import (
"net"
"strings"
)
type Listener net.Listener
type Conn net.Conn
func Listen(address string, handle func(Conn, *Package)) Listener {
splited := strings.Split(address, ":")
if len(splited) != 2 {
return nil
}
listener, err := net.Listen("tcp", "0.0.0.0:"+splited[1])
if err != nil {
return nil
}
go serve(listener, handle)
return Listener(listener)
}
func serve(listener net.Listener, handle func(Conn, *Package)) {
defer listener.Close()
for {
conn, err := listener.Accept()
if err != nil {
break
}
go handleConn(conn, handle)
}
}
func handleConn(conn net.Conn, handle func(Conn, *Package)) {
defer conn.Close()
pack := readPackage(conn)
if pack == nil {
return
}
handle(Conn(conn), pack)
}
func Send(address string, pack *Package) *Package {
conn, err := net.Dial("tcp", address)
if err != nil {
return nil
}
conn.Write([]byte(SerializePackage(pack) + ENDBYTES))
return readPackage(conn)
}
func Handle(option string, conn Conn, pack *Package, handle func(*Package) string) bool {
if pack.Option != option {
return false
}
conn.Write([]byte(SerializePackage(&Package{
Option: option,
Data: handle(pack),
}) + ENDBYTES))
return true
}
func readPackage(conn net.Conn) *Package {
var (
data string
size = uint64(0)
buffer = make([]byte, BUFFSIZE)
)
for {
length, err := conn.Read(buffer)
if err != nil {
return nil
}
size += uint64(length)
if size > DMAXSIZE {
return nil
}
data += string(buffer[:length])
if strings.Contains(data, ENDBYTES) {
data = strings.Split(data, ENDBYTES)[0]
break
}
}
return DeserializePackage(data)
}