1 Star 1 Fork 0

片片/SerialToNet

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
main.go 3.47 KB
一键复制 编辑 原始数据 按行查看 历史
片片 提交于 2022-01-22 11:47 . 测试通过
package main
import (
"flag"
"fmt"
"io"
"log"
"net"
"sync"
"github.com/jacobsa/go-serial/serial"
)
//串口类型
const TYPE_SERIAL = "serial"
//网络类型
const TYPE_NET = "network"
//高试模式设置
var DBG = false
var WAIT sync.WaitGroup
//任务取消标志
var IS_CANNEL = false
//ip地址
type NetOption struct {
IP string
Port int
}
//pipe对象
type PipeIO struct {
IO io.ReadWriteCloser
Dev string
IsClose bool
}
//关闭io并设置关闭标志
func (p *PipeIO) Close() {
if p.IO != nil {
p.IO.Close()
p.IsClose = true
}
}
//按照配置打开串口
func NewSerial() (PipeIO, error) {
serial_io := PipeIO{
Dev: TYPE_SERIAL,
IsClose: true,
}
ser_io, err := serial.Open(AppConfig.Serial_Opt)
if err != nil {
log.Printf("串口%v打开错误:%v\n", AppConfig.Serial_Opt.PortName, err.Error())
serial_io.IO = nil
} else {
log.Printf("串口已打开,串口名: %s; 波特率: %d\n", AppConfig.Serial_Opt.PortName, AppConfig.Serial_Opt.BaudRate)
serial_io.IO = ser_io
serial_io.IsClose = false
}
return serial_io, err
}
/**
func (rw *io.ReadWriteCloser) WriterTo(dst io.ReadWriteCloser) (written int64, err error) {
}
**/
func Pipe(data_to *PipeIO, data_frm *PipeIO, wt *sync.WaitGroup) {
defer data_to.Close()
defer data_frm.Close()
defer wt.Done()
_, err := DataCopy(data_to, data_frm)
if err != nil {
log.Printf("透传错误,请检查网络及设备连接:%v\n", err.Error())
}
}
//内存数据复制
func DataCopy(p_to *PipeIO, p_frm *PipeIO) (written int64, err error) {
buf := make([]byte, 32*1024)
for {
//判断任务是否取消
if IS_CANNEL {
break
}
nr, er := p_frm.IO.Read(buf)
if nr > 0 {
nw, ew := p_to.IO.Write(buf[0:nr])
if nw > 0 {
written += int64(nw)
}
if ew != nil {
err = ew
//发送错误通知
IS_CANNEL = true
p_frm.IO.Write([]byte(fmt.Sprintf("%s write error...", p_to.Dev)))
break
}
if nr != nw {
err = io.ErrShortWrite
break
}
}
if DBG {
log.Printf("透传数据[%s--->%s]: %v\n", p_frm.Dev, p_to.Dev, string(buf[0:nr]))
}
if er == io.EOF {
break
}
if er != nil {
err = er
//发送错误通知
IS_CANNEL = true
p_to.IO.Write([]byte(fmt.Sprintf("%s read error...", p_frm.Dev)))
break
}
}
return written, err
}
func main() {
//读取设置
if !Read_config() {
return
}
flag.BoolVar(&DBG, "debug", false, "是否开启调试模式,调试模式会输出一些运行中信息")
flag.Parse()
serial_pipe, err := NewSerial()
if err != nil {
return
}
nlistener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", AppConfig.Net_Opt.IP, AppConfig.Net_Opt.Port))
if err != nil {
log.Printf("网络监听错误,请检查端口是否被占用或无权限:%v\n", err.Error())
return
}
net_pipe := PipeIO{
Dev: TYPE_NET,
IsClose: false,
}
for {
IS_CANNEL = false
if serial_pipe.IsClose {
serial_pipe, err = NewSerial()
if err != nil {
break
}
}
log.Printf("网络正在监听[IP:%s:%d]......", AppConfig.Net_Opt.IP, AppConfig.Net_Opt.Port)
n_conn, err := nlistener.Accept()
if err != nil {
log.Printf("网络连接错误:%v\n", err.Error())
continue
}
net_pipe.IO = n_conn
net_pipe.IsClose = true
WAIT.Add(2)
go Pipe(&serial_pipe, &net_pipe, &WAIT)
go Pipe(&net_pipe, &serial_pipe, &WAIT)
WAIT.Wait()
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/zqpian/serial-to-net.git
git@gitee.com:zqpian/serial-to-net.git
zqpian
serial-to-net
SerialToNet
master

搜索帮助