go语言文件接收

Mayday920723 · · 1496 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

// modemfilesender.go

 

package main

 

import (

"os"

"syscall"

"fmt"

"log"

"serial"

"io/ioutil"

)

const (

R_SUCC = iota

R_FAIL

R_TIMEOUT

)

 

var rxwincnt int

var txwincnt int

var txpktcnt int

var rxpktcnt int

var prevwincnt int

var rxpktindiarr []byte

var payloadsiz int

var lastpayloadsiz int

var rbuf []byte

 

func main() {

if len(os.Args) != 2 {

fmt.Println("Usage: ", os.Args[0], "</dev/ttyUSBx>")

os.Exit(1)

}

c := &serial.Config{Name: os.Args[1], Baud: 115200}

s, err := serial.OpenPort(c)

if err != nil {

log.Fatal(err)

}

s.Flush()

fd := int(s.Fd())

defer s.Close()

mfphdr := make([]byte, 8)

pktresp := make([]byte, 16)

mmtdnbuf := make([]byte, 64)

sentack := false

for {

var payloadlen int

ret := readMfpHdr(fd, mfphdr, 15e3)

if ret == R_SUCC {

if sentack == true {

sentack = false

rxwincnt = 0

}

hi := uint(mfphdr[2])

lo := uint(mfphdr[3])

if txwincnt == 0 {

txwincnt = int(mfphdr[5])

}

if txpktcnt == 0 {

txpktcnt = int(mfphdr[7])

rxpktindiarr = make([]byte, txpktcnt)

}

pktidx := int(mfphdr[6])

if rxpktindiarr[pktidx] == 0 {

rxpktindiarr[pktidx] = 1

rxpktcnt++

}

payloadlen = int((hi << 8) | lo)

if payloadsiz == 0 {

payloadsiz = payloadlen;

rbuf = make([]byte, txpktcnt * payloadlen)

}

if txpktcnt - 1 == pktidx {

lastpayloadsiz = payloadlen

}

fmt.Println("read succ: ", hi, lo, payloadlen, mfphdr)

readFully(fd, rbuf[payloadsiz*pktidx:payloadsiz*pktidx + payloadlen], 15e3)

// fmt.Println("read mfp payload passed", rbuf[:payloadlen])

rxwincnt++

pktresp[rxwincnt] = mfphdr[6]

fmt.Printf("rxwincnt = %d, mfphdr[6] = %d\n", rxwincnt, int(mfphdr[6]))

}

if rxwincnt > 0 && (txwincnt == rxwincnt || ret == R_TIMEOUT) {

pktresp[0] = byte(rxwincnt)

fmt.Println("write ack:", pktresp[:rxwincnt+1])

s.Write(pktresp[:rxwincnt+1])

read_tx_done(fd, mmtdnbuf, 15e3)

sentack = true

txwincnt = 0

if rxpktcnt == txpktcnt {

fmt.Println("fin")

ioutil.WriteFile("mfp.dat", rbuf[:payloadsiz * (txpktcnt-1) + lastpayloadsiz], 0666)

break

}

}

}

}

func readFully(fd int, buf []byte, to int) (ret int) {

var event syscall.EpollEvent

var events [16]syscall.EpollEvent

ret = R_TIMEOUT

 

epfd, err := syscall.EpollCreate1(0)

if err != nil {

log.Fatal(err)

}

defer syscall.Close(epfd)

event.Events = syscall.EPOLLIN

event.Fd = int32(fd)

err = syscall.EpollCtl(epfd, syscall.EPOLL_CTL_ADD, fd, &event)

if err != nil {

log.Fatal(err)

}

pos := 0

length := len(buf)

fin:

for {

nevents, err := syscall.EpollWait(epfd, events[:], to)

if err != nil {

log.Fatal(err)

}

if nevents == 0 {

fmt.Println("epoll_wait = 0")

continue;

}

for ev := 0; ev < nevents; ev++ {

if int(events[ev].Fd) == fd {

nbytes, err := syscall.Read(fd, buf[pos:length])

if err != nil {

log.Fatal()

}

pos += nbytes

if pos == length {

ret = R_SUCC

break fin

}

}

}

}

return ret

}

func readMfpHdr(fd int, buf []byte, to int) (ret int) {

var event syscall.EpollEvent

var events [16]syscall.EpollEvent

ret = R_TIMEOUT

 

epfd, err := syscall.EpollCreate1(0)

if err != nil {

log.Fatal(err)

}

defer syscall.Close(epfd)

event.Events = syscall.EPOLLIN

event.Fd = int32(fd)

err = syscall.EpollCtl(epfd, syscall.EPOLL_CTL_ADD, fd, &event)

if err != nil {

log.Fatal(err)

}

pos := 0

scanbuf := make([]byte, 1)

length := len(buf)

fin:

for {

nevents, err := syscall.EpollWait(epfd, events[:], to)

if err != nil {

log.Fatal(err)

}

if nevents == 0 {

fmt.Println("epoll_wait = 0")

continue;

}

for ev := 0; ev < nevents; ev++ {

if int(events[ev].Fd) == fd {

nbytes, err := syscall.Read(fd, scanbuf)

if err != nil {

log.Fatal()

}

if pos == 0 && scanbuf[0] != 'M' {

continue

} else if pos == 1 && scanbuf[0] != 'F' {

pos = 0

continue

}

buf[pos] = scanbuf[0]

pos += nbytes

if pos == length {

ret = R_SUCC

break fin

}

}

}

}

return ret

}

func read_tx_done(fd int, buf []byte, to int) (int, error) {

var event syscall.EpollEvent

var events [4]syscall.EpollEvent

 

epfd, err := syscall.EpollCreate1(0)

if err != nil {

log.Fatal(err)

}

defer syscall.Close(epfd)

event.Events = syscall.EPOLLIN

event.Fd = int32(fd)

pos := 0

 

err = syscall.EpollCtl(epfd, syscall.EPOLL_CTL_ADD, fd, &event)

if err != nil {

log.Fatal(err)

}

for {

nevents, err := syscall.EpollWait(epfd, events[:], to)

if err != nil {

log.Fatal(err)

}

if nevents == 0 {

fmt.Println("epoll_wait = 0")

return 0, nil

}

for ev := 0; ev < nevents; ev++ {

if int(events[ev].Fd) == fd {

// fmt.Println("begin read...")

nbytes, err := syscall.Read(fd, buf[pos:])

if err != nil {

log.Fatal(err)

return nbytes, err

}

if nbytes > 0 {

pos += nbytes

if buf[pos-1] == '\n' {

fmt.Println(string(buf[:pos]))

return pos, nil

}

} else {

return 0, nil

}

}

}

}

return 0, nil

}

 


有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:Mayday920723

查看原文:go语言文件接收

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1496 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传