1 Star 0 Fork 1

flyiot/flylibs

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
server.go 2.62 KB
一键复制 编辑 原始数据 按行查看 历史
flyrainning 提交于 2023-03-03 16:52 +08:00 . u
// Package mbserver implments a Modbus server (slave).
package mbserver
import (
"errors"
"io"
"net"
)
// Server is a Modbus slave with allocated memory for discrete inputs, coils, etc.
type Server struct {
// Debug enables more verbose messaging.
ID uint8
Debug bool
listeners []net.Listener
ports []io.ReadWriteCloser
requestChan chan *Request
function [256](func(*Server, Framer) ([]byte, *Exception))
DiscreteInputs []byte
Coils []byte
HoldingRegisters []uint16
InputRegisters []uint16
}
// Request contains the connection and Modbus frame.
type Request struct {
conn io.ReadWriteCloser
frame Framer
}
// NewServer creates a new Modbus server (slave).
func NewServer() *Server {
s := &Server{}
// Allocate Modbus memory maps.
s.DiscreteInputs = make([]byte, 65536)
s.Coils = make([]byte, 65536)
s.HoldingRegisters = make([]uint16, 65536)
s.InputRegisters = make([]uint16, 65536)
// Add default functions.
s.function[1] = ReadCoils
s.function[2] = ReadDiscreteInputs
s.function[3] = ReadHoldingRegisters
s.function[4] = ReadInputRegisters
s.function[5] = WriteSingleCoil
s.function[6] = WriteHoldingRegister
s.function[15] = WriteMultipleCoils
s.function[16] = WriteHoldingRegisters
s.requestChan = make(chan *Request)
go s.handler()
return s
}
func (s *Server) SetID(id uint8) {
s.ID = id
}
// RegisterFunctionHandler override the default behavior for a given Modbus function.
func (s *Server) RegisterFunctionHandler(funcCode uint8, function func(*Server, Framer) ([]byte, *Exception)) {
s.function[funcCode] = function
}
func (s *Server) handle(request *Request) (Framer, error) {
var exception *Exception
var data []byte
response := request.frame.Copy()
//检查ID
slaveid := request.frame.GetID()
if slaveid != 0 {
if (s.ID != 0) && (slaveid != s.ID) {
return nil, errors.New("ID Error")
}
}
function := request.frame.GetFunction()
if s.function[function] != nil {
data, exception = s.function[function](s, request.frame)
response.SetData(data)
} else {
exception = &IllegalFunction
}
if exception != &Success {
response.SetException(exception)
}
return response, nil
}
// All requests are handled synchronously to prevent modbus memory corruption.
func (s *Server) handler() {
for {
request := <-s.requestChan
response, err := s.handle(request)
if err == nil {
request.conn.Write(response.Bytes())
}
}
}
// Close stops listening to TCP/IP ports and closes serial ports.
func (s *Server) Close() {
for _, listen := range s.listeners {
listen.Close()
}
for _, port := range s.ports {
port.Close()
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/flyiot/flylibs.git
git@gitee.com:flyiot/flylibs.git
flyiot
flylibs
flylibs
b9c81f1c9857

搜索帮助