Чтение данных из Socket Golang - PullRequest
0 голосов
/ 26 июня 2018

Я пытаюсь прочитать данные из сеанса telnet в golang. Я попытался выполнить следующие функции:

Изначально у меня возникла проблема, когда я читал из сокета без данных, поэтому он блокировался и никогда не возвращался. BufferSocketData - это моя попытка обойти эту проблему, так как я не могу знать, есть ли данные для чтения. Идея состоит в том, что он будет ждать 1 секунду, прежде чем определить, что в сокете нет данных, и вернуть пустую строку.

Кажется, что GetData работает в первый раз, когда в буфере появляются новые данные, но после этого он не получает новых данных. Я уверен, что это как-то связано с моим использованием горутинов и каналов, я новичок в работе и уверен, что не правильно их использую.

Есть идеи, почему мои последующие чтения не возвращают данных?

/*
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
    }
}

Пожалуйста, дайте мне знать, если вам нужна дополнительная информация.

1 Ответ

0 голосов
/ 26 июня 2018

Используйте SetReadDeadline для чтения данных с ограничением по времени:

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
    }
}

Обратите внимание, что один вызов Read может не прочитать все данные, отправленные партнером. Возможно, вы захотите накапливать данные, вызывая Read в цикле или вызывая io.ReadFull .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...