💬 Как устроен сетевой ввод-вывод в Go?
Сетевой ввод-вывод в Go организован через пакет
Когда мы создаем сетевое соединение или слушаем порт, каждая операция ввода-вывода (например, чтение или запись данных) может выполняться в отдельной горутине, позволяя обрабатывать множество соединений параллельно без блокировки главного потока выполнения.
Go автоматически управляет множеством горутин, что упрощает написание масштабируемого асинхронного сетевого кода по сравнению с традиционными подходами, основанными на потоках.
📌 Простой пример:
Сетевой ввод-вывод в Go организован через пакет
net
стандартной библиотеки, который предоставляет обширный API для работы с сетью. Он использует модель неблокирующего ввода-вывода с горутинами для обеспечения масштабируемости и эффективности. Когда мы создаем сетевое соединение или слушаем порт, каждая операция ввода-вывода (например, чтение или запись данных) может выполняться в отдельной горутине, позволяя обрабатывать множество соединений параллельно без блокировки главного потока выполнения.
Go автоматически управляет множеством горутин, что упрощает написание масштабируемого асинхронного сетевого кода по сравнению с традиционными подходами, основанными на потоках.
📌 Простой пример:
package main
import (
"fmt"
"io"
"net"
"os"
)
func main() {
// Слушаем на порту 8080
listener, err := net.Listen("tcp", ":8080")
if err != nil {
fmt.Println("Ошибка при создании слушателя:", err)
os.Exit(1)
}
defer listener.Close()
fmt.Println("Сервер запущен и слушает на порту 8080")
for {
// Принимаем входящее подключение
conn, err := listener.Accept()
if err != nil {
fmt.Println("Ошибка при принятии подключения:", err)
continue
}
// Обработка подключения в отдельной горутине
go handleConnection(conn)
}
}
// handleConnection обрабатывает отдельное подключение
func handleConnection(conn net.Conn) {
defer conn.Close()
fmt.Println("Подключился клиент:", conn.RemoteAddr().String())
// Отправляем сообщение клиенту
_, err := io.WriteString(conn, "Привет от сервера!\n")
if err != nil {
fmt.Println("Ошибка при отправке сообщения:", err)
return
}
fmt.Println("Сообщение отправлено клиенту:", conn.RemoteAddr().String())
}