TCP-клиент в Go
Клиент сам инициирует связь: указывает
протокол "tcp" и адрес с портом,
получает объект соединения и дальше
работает с ним как с потоком. Ошибку
открытия проверяют сразу; закрытие
ставят в отложенный вызов, чтобы канал
освободился при любом выходе из функции.
Отправка и прием идут через срез байтов. Запись возвращает, сколько байтов ушло; чтение кладет данные в буфер фиксированного размера и возвращает длину прочитанного куска. Текст на английском удобно переводить в байты литералом в кавычках.
Чтобы один запуск программы не требовал
отдельного процесса сервера, поднимем
простой ответчик в фоне, затем выполним
клиентскую часть в main:
package main
import (
"fmt"
"log"
"net"
"time"
)
func echoServer(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)
}
_, err = conn.Write(buf[:n])
if err != nil {
log.Fatal(err)
}
}
func main() {
addr := "127.0.0.1:9090"
go echoServer(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("hello"))
if err != nil {
log.Fatal(err)
}
buf := make([]byte, 256)
n, err := conn.Read(buf)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(buf[:n]))
}
На экране "hello". Клиент отправил
пять байтов, сервер вернул тот же кусок;
отложенное закрытие на стороне клиента
сработает перед выходом из main.
Тот же клиентский каркас без фонового сервера, если ответчик уже запущен отдельно:
package main
import (
"fmt"
"log"
"net"
)
func main() {
addr := "127.0.0.1:9090"
conn, err := net.Dial("tcp", addr)
if err != nil {
log.Fatal(err)
}
defer conn.Close()
_, err = conn.Write([]byte("ping"))
if err != nil {
log.Fatal(err)
}
buf := make([]byte, 256)
n, err := conn.Read(buf)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(buf[:n]))
}
Дан адрес:
addr := "127.0.0.1:9090"
Откройте исходящее TCP-соединение на
addr, отправьте "ok",
прочитайте ответ в буфер на 256
байт и выведите текст.
Дано сообщение для отправки:
msg := "data"
Запишите msg в соединение на
"127.0.0.1:9090" и закройте
канал отложенным вызовом.
Скажите, зачем на клиенте ставят закрытие соединения в отложенный вызов, даже если после чтения больше нет строк кода.