A comprehensive Modbus server library implemented in Go, supporting both TCP and RTU protocols with flexible storage backends.
- Multiple Protocol Support: Modbus TCP and RTU protocols
- Flexible Storage: In-memory and SQLite storage backends
- Standard Function Codes: Complete support for standard Modbus function codes
- Custom Handlers: Extensible callback system for custom function codes
- Concurrent Safe: Thread-safe operations with proper locking
- Configurable: Flexible configuration options
- Production Ready: Comprehensive test coverage and error handling
01
- Read Coils02
- Read Discrete Inputs03
- Read Holding Registers04
- Read Input Registers
05
- Write Single Coil06
- Write Single Register15
- Write Multiple Coils16
- Write Multiple Registers
go get github.com/hootrhino/goodbusserver
package main
import (
"log"
"github.com/hootrhino/goodbusserver"
"github.com/hootrhino/goodbusserver/store"
)
func main() {
// Create storage backend
store := store.NewInMemoryStore()
// Create and configure server
server := mbserver.NewServer(store)
// Start server
if err := server.Start(":502"); err != nil {
log.Fatal(err)
}
defer server.Stop()
log.Println("Modbus server started on :502")
select {}
}
// Set coil data
coils := []byte{0x01, 0x00, 0x01, 0x01}
store.SetCoils(coils)
// Set holding registers
registers := []uint16{1000, 2000, 3000, 4000}
store.SetHoldingRegisters(registers)
// Set coils at specific address
store.SetCoilsAt(100, []byte{0xFF, 0x00})
// Set holding registers at specific address
store.SetHoldingRegistersAt(200, []uint16{1234, 5678})
// Register custom function code handler
server.RegisterCustomHandler(0x81, func(request mbserver.Request, store store.Store) ([]byte, error) {
// Custom processing logic
response := []byte{request.FuncCode, 0x01, 0x02}
return response, nil
})
// Use SQLite for persistence
store, err := store.NewSqliteStore("modbus.db")
if err != nil {
log.Fatal(err)
}
defer store.Close()
server := mbserver.NewServer(store)
// Set timeout
server.SetTimeout(5 * time.Second)
// Set logger
server.SetLogger(log.New(os.Stdout, "MODBUS: ", log.LstdFlags))
// Set error handler
server.SetErrorHandler(func(err error) {
log.Printf("Server error: %v", err)
})
type Store interface {
GetCoils(start, quantity uint16) ([]byte, error)
GetDiscreteInputs(start, quantity uint16) ([]byte, error)
GetHoldingRegisters(start, quantity uint16) ([]uint16, error)
GetInputRegisters(start, quantity uint16) ([]uint16, error)
SetCoils(values []byte) error
SetDiscreteInputs(values []byte) error
SetHoldingRegisters(values []uint16) error
SetInputRegisters(values []uint16) error
SetCoilsAt(start uint16, values []byte) error
SetHoldingRegistersAt(start uint16, values []uint16) error
}
The library provides comprehensive error handling:
ErrIllegalFunction
- Invalid function codeErrIllegalDataAddress
- Invalid data addressErrIllegalDataValue
- Invalid data valueErrServerDeviceFailure
- Server device failure
Run the test suite:
go test -v ./...
See the examples/
directory for complete working examples:
- Basic TCP server
- RTU server
- SQLite persistence
- Custom handlers
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
This project is licensed under the GNU Affero General Public License v3.0 - see the LICENSE file for details.
- Initial release
- Complete Modbus TCP support
- In-memory and SQLite storage
- Comprehensive test coverage
- Custom handler support