TCP-соединение читает слишком много байтов одновременно - PullRequest
0 голосов
/ 18 апреля 2019

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

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

Это относительная часть с сервера:

for _, fn := range files {
    conn.Write([]byte(fn.Name()))
}

В приведенном выше коде files равно []os.FileInfo из ioutil.ReadDir("./"), чтобы получить файлы в текущем каталоге. При проверке это отправляет правильное имя файла, а также правильные байты для каждого имени.

На клиенте у меня это:

var buf [256]byte
for i := 0; i < int(amnt); i++ {
    n, err = conn.Read(buf[:])
    if err != nil {
        fmt.Printf("Error getting files: %s\n", err)
    }
    fmt.Printf("%s\n", string(buf[:n]))
}

int(amnt) это просто int для количества файлов в каталоге и является правильным.

Сервер отправляет все правильно, поэтому я уверен, что проблема заключается в чтении в buf, но я не могу понять, почему он будет считывать более одного имени файла одновременно.

1 Ответ

0 голосов
/ 18 апреля 2019

Одной из стратегий для решения этой проблемы может быть разработка свободно структурированного протокола, который будет включать в себя разграничение файлов клиентом и файлы синтаксического анализа на сервере. Это может быть сделано путем отправки новой строки после каждого файла, который пишет клиент. Таким образом, сервер может сканировать строки из TCP-соединения, используя go Scanner:

for _, fn := range files {
    conn.Write([]byte(fn.Name()))
    conn.Write([]byte(`\n`))
}
scanner := bufio.NewScanner(conn)
for {
        if ok := scanner.Scan(); !ok {
            break
        }
        fmt.Println(scanner.Text())
    }
    fmt.Println("Scanning ended")

Go делает это возможным, поскольку TCP-соединение реализует интерфейс io.Reader .

...