Ответ
TCP (Transmission Control Protocol) — это один из основных протоколов сетевой модели TCP/IP. Его главная задача — обеспечить надежную, упорядоченную и безошибочную доставку потока данных между двумя программами, запущенными на разных хостах в сети.
Ключевые характеристики TCP:
- Надежность (Reliability): Гарантирует, что данные будут доставлены. Если пакет теряется, TCP запрашивает его повторную отправку.
- Установка соединения (Connection-oriented): Перед обменом данными клиенту и серверу необходимо установить соединение через процесс "тройного рукопожатия" (three-way handshake: SYN, SYN-ACK, ACK).
- Упорядоченная доставка (Ordered Delivery): TCP гарантирует, что данные будут получены в том же порядке, в котором были отправлены.
- Контроль потока (Flow Control): Механизм, который не позволяет быстрому отправителю перегрузить медленного получателя.
Благодаря этим свойствам, TCP используется в большинстве популярных прикладных протоколов, где важна целостность данных: HTTP/HTTPS, FTP, SMTP, SSH, Telnet.
Примеры использования в Go:
В стандартной библиотеке Go (net) есть все необходимое для работы с TCP.
-
Простой TCP-сервер Сервер слушает порт, принимает входящие соединения и обрабатывает каждое в отдельной горутине.
package main import ( "fmt" "net" ) func handleConnection(conn net.Conn) { defer conn.Close() fmt.Printf("Accepted connection from %sn", conn.RemoteAddr()) // ... логика чтения/записи данных conn.Write([]byte("Hello from server!n")) } func main() { // Начинаем слушать порт 8080 по протоколу TCP ln, err := net.Listen("tcp", ":8080") if err != nil { panic(err) } defer ln.Close() fmt.Println("Server is listening on port 8080") for { // Ожидаем и принимаем новое соединение conn, err := ln.Accept() if err != nil { fmt.Println("Error accepting connection:", err) continue } // Обрабатываем соединение в новой горутине go handleConnection(conn) } } -
TCP-клиент Клиент устанавливает соединение с сервером, отправляет данные и читает ответ.
package main import ( "bufio" "fmt" "net" "time" ) func main() { // Устанавливаем соединение с таймаутом conn, err := net.DialTimeout("tcp", "localhost:8080", 5*time.Second) if err != nil { panic(err) } defer conn.Close() fmt.Println("Connected to server!") // Отправляем данные _, err = conn.Write([]byte("Hello, server!n")) if err != nil { panic(err) } // Читаем ответ от сервера message, _ := bufio.NewReader(conn).ReadString('n') fmt.Print("Message from server: " + message) }
В отличие от UDP, который является более быстрым, но ненадёжным протоколом без установки соединения, TCP выбирают тогда, когда потеря или нарушение порядка данных недопустимы.