代码拉取完成,页面将自动刷新
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()
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。