duan1989643
duan1989643
2018-06-26 15:08

从Socket Golang读取数据

  • sockets
已采纳

I'm trying to read data from a telnet session in golang. I wrote the following functions in an attempt to accomplish this.

Initially I was having an issue where I was reading from a socket with no data so it would lock and never return. BufferSocketData is my attempt to work around this issue as I can't know if there is data to read. The idea is it will wait 1 second before determining there is not data in the socket and return an empty string.

GetData seems to work the first time there is new data in the buffer, but beyond that it gets no new data. I'm sure this has something to do with my use of goroutines and channels, I'm new to go and I'm sure I'm not using them correctly.

Any ideas as to why my subsequent reads return no data?

/*
ReadDataFromSocket - Attempts to read any data in the socket.
*/
func ReadDataFromSocket(sock io.Reader, c chan string) {
    var recvData = make([]byte, 1024)
    var numBytes, _ = sock.Read(recvData)
    c <- string(recvData[:numBytes])
}

/*
BufferSocketData - Read information from the socket and store it in the buffer.
*/
func (tn *TelnetLib) BufferSocketData(inp chan string, out chan string) {
    var data string
    var timeout int64 = 1000 // 1 second timeout.
    var start = utils.GetTimestamp()

    for utils.GetTimestamp()-start < timeout {
        select {
        case data = <-inp:
        default:
        }
        if data != "" {
            break
        }
    }
    out <- data
}

/*
GetData - Start goroutines to get and buffer data.
*/
func (tn *TelnetLib) GetData() {
    var sockCh = make(chan string)
    var buffCh = make(chan string)

    go ReadDataFromSocket(tn.Conn, sockCh)
    go tn.BufferSocketData(sockCh, buffCh)

    var data = <-buffCh

    if data != "" {
        tn.Buffer += data
    }
}

Please let me know if you need any additional information.

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

1条回答

  • douaoren4402 douaoren4402 3年前

    Use SetReadDeadline to read data with a time limit:

    func (tn *TelnetLib) GetData() {
        tn.Conn.SetReadDeadline(time.Second)
        recvData := make([]byte, 1024)
        n, err := tn.Conn.Read(recvData)
        if n > 0 {
           // do something with recvData[:n]
        }
        if e, ok := err.(interface{ Timeout() bool }); ok && e.Timeout() {
            // handle timeout
        } else if err != nil {
           // handle error
        }
    }
    

    Note that a single call Read may not read all data sent by the peer. You may want to accumulate data by calling Read in a loop or call io.ReadFull.

    点赞 评论 复制链接分享

为你推荐