Nano Hash - криптовалюты, майнинг, программирование

простой сервер golang с интерактивной подсказкой

Я пытаюсь создать простой интерфейс CLI для моего процесса go, мне нужно слушать и обслуживать порт TCP и получать статистику при подключении к порту на TCP. Я наткнулся на пакет «терминал», чтобы помочь с запросом пароля, историей команд и другими вещами. Я попытался написать код для достижения этой цели. Хотя мой клиент не получает никакого запроса или сервер застрял на методе «ReadLine». Есть помощники?


package main

import (
    "bufio"
    "fmt"
    "golang.org/x/crypto/ssh/terminal"
    "io"
    "net"
    _ "time"
)

func handleConnection(conn net.Conn) error {
    fmt.Println("Handling new connection...")
    defer func() {
        fmt.Println("Closing connection...")
        conn.Close()
    }()
    r := bufio.NewReader(conn)
    w := bufio.NewWriter(conn)
    rw := bufio.NewReadWriter(r, w)
    term := terminal.NewTerminal(rw, "")
    term.SetPrompt(string(term.Escape.Red) + "> " + string(term.Escape.Reset))
    rePrefix := string(term.Escape.Cyan) + "Human says:" + string(term.Escape.Reset)
    line := "welcome"
    fmt.Fprintln(term, rePrefix, line)
    for {
        line, err := term.ReadLine()
        if err == io.EOF {
            return nil
        }
        if err != nil {
            return err
        }
        if line == "" {
            continue
        }
        fmt.Fprintln(term, rePrefix, line)
    }
}

func main() {
    // Start listening to port 8888 for TCP connection
    listener, err := net.Listen("tcp", ":8888")
    if err != nil {
        fmt.Println(err)
        return
    }

    defer func() {
        listener.Close()
        fmt.Println("Listener closed")
    }()

    for {
        // Get net.TCPConn object
        conn, err := listener.Accept()
        if err != nil {
            fmt.Println(err)
            break
        }

        go handleConnection(conn)
    }
}
03.05.2020

  • На сервере есть буферизованный модуль записи, поэтому не забудьте вызвать Flush, когда хотите отправить содержимое буфера в базовое сетевое соединение. Например, добавляйте w.Flush() после каждого fmt.Fprintln(term, rePrefix, line). 03.05.2020
  • Спасибо ! это устраняет одну проблему, и теперь клиент получает то, что отправляет сервер, хотя Readline все еще зависает после отправки данных от клиента. 03.05.2020
  • Извините, не могли бы вы подтвердить, добавили ли вы два вызова Flush на сервер? Один после записи перед циклом и один после записи внутри цикла? 03.05.2020
  • Да, верно, проблема в 'term.ReadLine()', который не разблокируется после отправки данных клиентом. 03.05.2020
  • Я могу запустить ваш сервер локально и подключиться к нему через telnet localhost 8888. С вызовами Flush это работает так, как задумано: каждая строка, отправленная telnet, возвращается с сервера. Он не застрял на методе ReadLine. Поэтому, возможно, проверьте, что ваш клиент отправляет правильно. Если это клиент go, возможно, это та же проблема, буферизованный писатель не сбрасывает. 04.05.2020
  • @Mark Большое спасибо, раньше я использовал «nc», и это приводило к зависанию ReadLine. Еще раз спасибо ! 04.05.2020
  • Хорошо. Также вы можете использовать nc -C ...., где флаг -C означает, что каждый символ перевода строки (LF) из входных данных преобразуется в CR+LF перед записью в сокет. 04.05.2020
  • Опять же, с этим также поведение странное, я не получаю подсказку, и ввод не отображается, пока я не нажму ввод, а затем отобразится мой ввод и подсказка. Я предполагаю, что он буферизуется и не отображается, пока я не нажму Enter. Есть ли способ сделать его естественным play.golang.org/p/bYt_muOICgp . Здесь «хороший()» работает хорошо, а «плохой()» имеет описанную проблему. 05.05.2020

Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..