← Назад к вопросам
Приведи примеры использования TCP
1.0 Junior🔥 141 комментариев
#Сетевые протоколы и API
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Примеры использования TCP в Go
Что такое TCP?
TCP (Transmission Control Protocol) — это протокол надёжной доставки данных по сети. В отличие от UDP, TCP гарантирует:
- Доставку всех пакетов
- Порядок передачи данных
- Отсутствие дублей
Транспортный уровень OSI.
Пример 1: TCP Сервер
package main
import (
"fmt"
"log"
"net"
)
func main() {
// Слушаем на порту 8080
listener, err := net.Listen("tcp", ":8080")
if err != nil {
log.Fatal("Listen error:", err)
}
defer listener.Close()
fmt.Println("Server listening on :8080")
for {
// Принимаем входящее соединение
conn, err := listener.Accept()
if err != nil {
log.Println("Accept error:", err)
continue
}
// Обрабатываем в отдельной горутине
go handleConnection(conn)
}
}
func handleConnection(conn net.Conn) {
defer conn.Close()
// Читаем данные от клиента
buffer := make([]byte, 1024)
n, err := conn.Read(buffer)
if err != nil {
log.Println("Read error:", err)
return
}
message := string(buffer[:n])
fmt.Printf("Получено: %s\n", message)
// Отправляем ответ
response := fmt.Sprintf("Вы отправили: %s", message)
conn.Write([]byte(response))
}
Пример 2: TCP Клиент
package main
import (
"fmt"
"log"
"net"
)
func main() {
// Подключаемся к серверу
conn, err := net.Dial("tcp", "localhost:8080")
if err != nil {
log.Fatal("Connection error:", err)
}
defer conn.Close()
// Отправляем сообщение
message := "Hello from client"
_, err = conn.Write([]byte(message))
if err != nil {
log.Fatal("Write error:", err)
}
// Получаем ответ
buffer := make([]byte, 1024)
n, err := conn.Read(buffer)
if err != nil {
log.Fatal("Read error:", err)
}
response := string(buffer[:n])
fmt.Println("Ответ сервера:", response)
}
Пример 3: HTTP Сервер (TCP поверх)
HTTP использует TCP под капотом:
package main
import (
"fmt"
"net/http"
)
func main() {
// net.http.Server слушает на TCP порту
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World!")
})
http.HandleFunc("/api/users", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
fmt.Fprintf(w, `{"users": ["Alice", "Bob"]}`)
})
// Слушаем на TCP :8080
fmt.Println("HTTP Server on :8080")
http.ListenAndServe(":8080", nil)
}
Пример 4: Чат (двусторонняя коммуникация)
package main
import (
"bufio"
"fmt"
"log"
"net"
"strings"
)
func main() {
listener, _ := net.Listen("tcp", ":3000")
defer listener.Close()
fmt.Println("Chat server on :3000")
for {
conn, _ := listener.Accept()
go handleChat(conn)
}
}
func handleChat(conn net.Conn) {
defer conn.Close()
reader := bufio.NewReader(conn)
for {
// Читаем строку (до \n)
message, err := reader.ReadString(
)
if err != nil {
fmt.Println("Client disconnected")
return
}
message = strings.TrimSpace(message)
fmt.Printf("[Client]: %s\n", message)
// Отправляем эхо
response := fmt.Sprintf("Echo: %s\n", message)
conn.Write([]byte(response))
}
}
Пример 5: RPC сервер (удалённые вызовы процедур)
package main
import (
"fmt"
"log"
"net"
"net/rpc"
)
// Сервис с методами
type Math struct{}
func (m *Math) Add(args [2]int, reply *int) error {
*reply = args[0] + args[1]
return nil
}
func (m *Math) Multiply(args [2]int, reply *int) error {
*reply = args[0] * args[1]
return nil
}
func main() {
// Регистрируем сервис
math := new(Math)
rpc.Register(math)
// Слушаем TCP соединения
listener, err := net.Listen("tcp", ":1234")
if err != nil {
log.Fatal(err)
}
defer listener.Close()
fmt.Println("RPC server on :1234")
for {
conn, _ := listener.Accept()
go rpc.ServeConn(conn) // Обработка RPC вызовов
}
}
// RPC клиент
package main
import (
"fmt"
"log"
"net/rpc"
)
func main() {
// Подключаемся к RPC серверу
client, err := rpc.Dial("tcp", "localhost:1234")
if err != nil {
log.Fatal(err)
}
defer client.Close()
// Вызываем удалённый метод
var result int
err = client.Call("Math.Add", [2]int{5, 3}, &result)
if err != nil {
log.Fatal(err)
}
fmt.Println("5 + 3 =", result) // Выведет 8
}
Пример 6: gRPC (современное RPC)
// service.proto
syntax = "proto3";
service Calculator {
rpc Add(AddRequest) returns (AddResponse);
}
message AddRequest {
int32 a = 1;
int32 b = 2;
}
message AddResponse {
int32 result = 1;
}
// server.go
package main
import (
"context"
"fmt"
"log"
"net"
"google.golang.org/grpc"
)
type Server struct{}
func (s *Server) Add(ctx context.Context, req *AddRequest) (*AddResponse, error) {
return &AddResponse{Result: req.A + req.B}, nil
}
func main() {
listener, _ := net.Listen("tcp", ":50051")
grpcServer := grpc.NewServer()
RegisterCalculatorServer(grpcServer, &Server{})
grpcServer.Serve(listener) // Слушаем TCP
}
Пример 7: Прокси сервер
package main
import (
"fmt"
"io"
"log"
"net"
)
func main() {
listener, _ := net.Listen("tcp", ":9000")
defer listener.Close()
fmt.Println("Proxy on :9000 -> :8080")
for {
clientConn, _ := listener.Accept()
go proxy(clientConn)
}
}
func proxy(clientConn net.Conn) {
defer clientConn.Close()
// Подключаемся к целевому серверу
serverConn, err := net.Dial("tcp", "localhost:8080")
if err != nil {
log.Println("Cannot connect to server:", err)
return
}
defer serverConn.Close()
// Двусторонняя передача данных
go io.Copy(serverConn, clientConn) // Клиент -> Сервер
io.Copy(clientConn, serverConn) // Сервер -> Клиент
}
Пример 8: Подключение к существующему сервису
func ConnectToDatabase(host string, port int) (net.Conn, error) {
addr := fmt.Sprintf("%s:%d", host, port)
// TCP соединение к БД (например PostgreSQL)
conn, err := net.Dial("tcp", addr)
if err != nil {
return nil, fmt.Errorf("database connection failed: %w", err)
}
return conn, nil
}
// MySQL
var db, _ = sql.Open("mysql", "user:password@tcp(localhost:3306)/dbname")
// PostgreSQL
var db, _ = sql.Open("postgres", "user=postgres host=localhost port=5432 dbname=testdb sslmode=disable")
Ключевые функции TCP в Go
| Функция | Назначение |
|---|---|
net.Listen("tcp", addr) | Создать TCP сервер |
net.Dial("tcp", addr) | Подключиться к TCP серверу |
listener.Accept() | Принять входящее соединение |
conn.Read() | Прочитать данные |
conn.Write() | Отправить данные |
conn.Close() | Закрыть соединение |
bufio.Scanner() | Читать строками |
Заключение
ТCP в Go используется для:
- HTTP/REST сервисов (основа веб-приложений)
- Микросервисной архитектуры (gRPC, RPC)
- Баз данных (PostgreSQL, MySQL на TCP портах)
- Чатов и real-time приложений
- Прокси и балансировщиков нагрузки
- Любых приложений требующих надёжной доставки