Следите за новинками
в нашем Telegram канале. Жми, чтобы подписаться:)
⊗goSpSoSv 251 of 280 menu
◀ ▶

TCP-сервер в Go

Сервер не инициирует связь сам: он объявляет, что готов принимать TCP на заданном адресе, и ждет первого клиента. Объект слушателя держит порт открытым; когда клиент подключится, отдельный объект соединения представляет уже установленный канал с этим клиентом.

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

Один клиент и простая печать прочитанного куска:

package main import ( "fmt" "log" "net" "time" ) func serveOnce(addr string) { ln, err := net.Listen("tcp", addr) if err != nil { log.Fatal(err) } defer ln.Close() conn, err := ln.Accept() if err != nil { log.Fatal(err) } defer conn.Close() buf := make([]byte, 256) n, err := conn.Read(buf) if err != nil { log.Fatal(err) } fmt.Println(string(buf[:n])) } func main() { addr := "127.0.0.1:9090" go serveOnce(addr) time.Sleep(10 * time.Millisecond) conn, err := net.Dial("tcp", addr) if err != nil { log.Fatal(err) } defer conn.Close() _, err = conn.Write([]byte("server test")) if err != nil { log.Fatal(err) } time.Sleep(50 * time.Millisecond) }

На экране сервера "server test". Клиент в main нужен только чтобы отправить строку; в следующих уроках ответ пойдет обратно в то же соединение.

Тот же серверный каркас без клиента в том же файле, если проверку делаете вручную второй программой:

package main import ( "fmt" "log" "net" ) func main() { addr := "127.0.0.1:9090" ln, err := net.Listen("tcp", addr) if err != nil { log.Fatal(err) } defer ln.Close() conn, err := ln.Accept() if err != nil { log.Fatal(err) } defer conn.Close() buf := make([]byte, 256) n, err := conn.Read(buf) if err != nil { log.Fatal(err) } fmt.Println("got", string(buf[:n])) }

Дан адрес:

addr := "127.0.0.1:9090"

Привяжите слушатель к addr по протоколу TCP, примите одно соединение и закройте слушатель отложенным вызовом.

Дан фрагмент после успешного принятия:

conn, err := ln.Accept() if err != nil { log.Fatal(err) }

Допишите отложенное закрытие conn и чтение в буфер 256 байт.

Скажите, чем объект слушателя отличается от объекта соединения после принятия клиента.

← →
↑
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить