Similar presentations:
Лекция 06.11.26
1.
Сокеты в компьютерных сетяхTCP-клиент и сервер на Go
Как приложения устанавливают соединение
и обмениваются сообщениями
КЛИЕНТ
СЕРВЕР
запрос и ответ по TCP
01
2.
Что такое сокетСокет — конечная точка обмена данными,
которую операционная система предоставляет программе.
127.0.0.1 : 9000
IP-адрес компьютера
Порт приложения
TCP-соединение определяют локальный и удалённый
IP-адреса и порты. 127.0.0.1 означает этот компьютер.
02
3.
TCP и UDPTCP
UDP
Соединение перед обменом
Обмен отдельными датаграммами
Поток байтов по порядку
Порядок и доставка без гарантий
Повторная передача при потерях
Повторы задаёт приложение
Пример: HTTP/1.1 и HTTP/2
Пример: DNS-запросы по UDP
03
4.
Жизненный цикл TCP-соединенияСервер
Клиент
1. Listen: открыть порт
1. Dial: подключиться к серверу
2. Accept: принять соединение
2. Write: отправить запрос
3. Read / Write: обменяться данными
3. Read: получить ответ
4. Close: закрыть соединение
4. Close: закрыть соединение
Accept возвращает новое соединение. Listener продолжает принимать клиентов.
04
5.
Границы сообщений в TCPОдна запись Write может потребовать нескольких чтений Read.
Несколько записей могут прийти в одном чтении.
Отправляем:
Получаем:
Сообщение:
"Привет" + "\n"
"При" + "вет\n"
"Привет"
05
6.
Go: сервер принимает клиентовfunc main() {
ln, err := net.Listen("tcp", "127.0.0.1:9000")
if err != nil {
log.Fatal(err)
}
fmt.Println("--------------- Sever started ---------------")
defer ln.Close()
for {
c, err := ln.Accept()
if err != nil {
log.Fatal(err)
}
go handle(c)
}
}
Каждое соединение обслуживает отдельная горутина.
Полный файл: server/main.go.
06
7.
Go: сервер читает строку и отвечаетfunc handle(c net.Conn) {
defer c.Close()
s := bufio.NewScanner(c)
for s.Scan() {
if _, err := fmt.Fprintln(c, "Запрос на сервер: "+c.LocalAddr().String()+" отправлен"); err !=
nil {
log.Print(err)
return
}
fmt.Println("Новое запрос с адреса - " + s.Text())
}
if err := s.Err(); err != nil {
log.Print(err)
}
}
07
8.
Go: клиент отправляет запросfunc main() {
c, err := net.Dial("tcp", "127.0.0.1:9000")
if err != nil {
log.Fatal(err)
}
defer c.Close()
if _, err := fmt.Fprintln(
c,
c.LocalAddr(),
); err != nil {
log.Print(err)
return
}
msg, err := bufio.NewReader(c).ReadString('\n')
if err != nil {
log.Print(err)
return
}
fmt.Print(msg)
}
Полный файл: client/main.go.
08
9.
Запуск примераТерминал 1: сервер
go run ./server/main.go
Терминал 2: клиент
go run ./client/main.go
echo: Привет, сокеты!
Команды выполняются из папки sockets-go. Нужен установленный Go.
Остановка сервера: Ctrl+C. Пример работает на одном компьютере.
09
programming