/*
* @Author: Robin
* @Date: 2020-02-20 17:38:31
* @LastEditors: Robin
* @LastEditTime: 2020-02-21 12:55:25
* @Description: 虚拟串口,仅适用与Linux/Mac
*/
package main
import (
"flag"
"fmt"
"log"
"os"
"sync"
"github.com/creack/pty"
"golang.org/x/crypto/ssh/terminal"
)
var wg sync.WaitGroup
func main() {
// 处理启动参数
num := flag.Int("num", 1, "serial number")
flag.Parse()
for i := 0; i < *num; i++ {
pty1, t1, err := pty.Open()
if err != nil {
log.Fatalln(err)
}
terminal.MakeRaw(int(t1.Fd())) // 设置为Raw模式,防止控制字符丢失
pty2, t2, err := pty.Open()
if err != nil {
log.Fatalln(err)
}
terminal.MakeRaw(int(t2.Fd())) // 设置为Raw模式,防止控制字符丢失
go tty1(t1, t2, pty1, pty2)
go tty2(t1, t2, pty1, pty2)
fmt.Println("Virtual Serial Port:", t1.Name(), "<===>", t2.Name())
}
wg = sync.WaitGroup{}
wg.Add(1)
wg.Wait()
}
// 串口1
func tty1(tty1, tty2, pty1, pty2 *os.File) {
var n int
var err error
buf := make([]byte, 1024)
for {
n, err = pty1.Read(buf)
if err != nil {
log.Fatalln(tty1.Name(), "Read Error", err.Error())
}
_, err = pty2.Write(buf[:n])
if err != nil {
log.Fatalln(tty2.Name(), "Write Error", err.Error())
}
}
}
// 串口2
func tty2(tty1, tty2, pty1, pty2 *os.File) {
var n int
var err error
buf := make([]byte, 1024)
for {
n, err = pty2.Read(buf)
if err != nil {
log.Fatalln(tty2.Name(), "Read Error", err.Error())
}
_, err = pty1.Write(buf[:n])
if err != nil {
log.Fatalln(tty1.Name(), "Write Error", err.Error())
}
}
}
一键复制
编辑
Web IDE
原始数据
按行查看
历史