TCP на сервер Redis с заблокированным каналом - PullRequest
0 голосов
/ 23 сентября 2018

Мне нужно отправить echo aaa три раза на сервер redis, но он застрял в середине процесса, я также проверяю, появляется ли сообщение об ошибке при операции read и write, но это не так.Итак, почему он застрял в середине процесса?

package main



import (
    "fmt"
    "os"
    "io"
    "net"
    "sync"
)

var (
    wg = new(sync.WaitGroup)
)

func readFromServer(isWrite chan bool, r io.Reader) {
    for {
        select {
        case <-isWrite:
            _ , err := io.Copy(os.Stdout, r)
            if err != nil {
                panic(err)
            }
        }
    }
}

func writeToServer(conn net.Conn , isWrite chan bool ){
    defer wg.Done()
    for i :=0; i<3; i++{
        _ , err := conn.Write([]byte("*2\r\n$4\r\necho\r\n$3\r\naaa\r\n"))
        if err != nil {
            panic(err)
        }
        isWrite<- true
    }
}

func main(){
    wg.Add(1)

    conn ,err := net.Dial("tcp","127.0.0.1:6379")
    isWrite := make(chan bool)

    if err != nil {
        panic(err)
    }

    go readFromServer(isWrite, conn)
    go writeToServer(conn , isWrite)



    wg.Wait()
    fmt.Println("finished...")
}

Вывод:

$3
aaa
$3
aaa
Stuck here...

1 Ответ

0 голосов
/ 23 сентября 2018

Функция readFromServer получает одно значение из канала isWrite и затем блокирует вызов io.Copy.Функция io.Copy не возвращается до EOF или какой-либо ошибки чтения или записи данных.Весь вывод программы происходит из одного вызова io.Copy.

Второй отправка isWrite в блоках sendToServer.Канал isWrite является небуферизованным каналом.Отправка по небуферизованному каналу не продолжается до тех пор, пока не будет получен приемник.На канале нет получателя, потому что readFromServer заблокирован при вызове io.Copy.

Возможные исправления:

  • Исправление заключается в изменении readFromServer для анализаRESP протокол и читать ровно одно сообщение за итерацию в цикле.

  • Заменить цикл в readFromServer одним вызовом io.Copy.

Канал isWrite не нужен.

Программа не гарантирует, что readFromServer прочитает все ответы из writeToServer до выхода из программы.

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