
I'r rhai sydd Ymroddedig i ddeall rhwydweithiau a phrotocolau.
Yn fyr
Mae'r erthygl yn trafod hanfodion trosglwyddo data dibynadwy, yn gweithredu enghreifftiau ar , gan gynnwys CDU a TCP. Yn seiliedig ar , , a'r llyfrau "Computer Networks. Top-Down Approach", fel arall mae pawb yn trafod Tannenbaum ac Oliferov yn unig.
Protocol haen trafnidiaeth
Yn darparu cysylltiad rhesymegol rhwng prosesau ymgeisio sy'n rhedeg ar wahanol westeion. O safbwynt cymhwysiad, mae cysylltiad rhesymegol yn edrych fel sianel sy'n cysylltu prosesau'n uniongyrchol.

yn cael eu cefnogi gan systemau diwedd, ond nid gan lwybryddion rhwydwaith (ac eithrio - ). Ar ochr yr anfonwr, mae'r haen trafnidiaeth yn trosi'r data haen cais y mae'n ei dderbyn o'r broses ymgeisio anfon yn becynnau haen trafnidiaeth o'r enw segmentau.

Gwneir hyn trwy rannu (os oes angen) y negeseuon haen cais yn ddarnau ac ychwanegu pennawd haen gludo i bob un ohonynt.

Yna mae'r haen drafnidiaeth yn trosglwyddo'r segment i haen rhwydwaith yr anfonwr, lle mae'r segment wedi'i grynhoi mewn pecyn haen rhwydwaith (datagram) a'i anfon. Ar y pen derbyn, mae'r haen rhwydwaith yn tynnu'r segment haen trafnidiaeth o'r datagram ac yn ei drosglwyddo i'r haen drafnidiaeth. Nesaf, mae'r haen drafnidiaeth yn prosesu'r segment a dderbynnir fel bod ei ddata ar gael i'r cais sy'n derbyn.

Egwyddorion trosglwyddo data dibynadwy
Trosglwyddo data dibynadwy dros sianel gwbl ddiogel
Yr achos symlaf. Mae'r ochr anfon yn syml yn derbyn y data o'r haen uchaf, yn creu pecyn sy'n ei gynnwys, ac yn ei anfon i'r sianel.
Gweinydd
package main
import (
"log"
"net"
)
func main() {
// IP-адрес сервера и порт
serverAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:12000")
if err != nil {
log.Fatal(err)
}
// создаем сокет с портом
serverConn, err := net.ListenUDP("udp", serverAddr)
if err != nil {
log.Fatal(err)
}
// отложенное закрытие соединения
defer serverConn.Close()
// создаем буфер для данных
buf := make([]byte, 1024)
// ждем соединение
for {
// читаем запрос
n, addr, err := serverConn.ReadFromUDP(buf)
// передаем данные в ВЕРХНИЙ уровень: в нашем случае stdout
println(string(buf[0:n]), " form ", addr.IP.String())
if err != nil {
log.Fatal(err)
}
// ответа нет, т.к. это UDP + надежный канал
}
}Cwsmer
package main
import (
"fmt"
"log"
"net"
"time"
)
func main() {
// IP-адрес сервера и порт
serverAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:12000")
if err != nil {
log.Fatal(err)
}
// локальный IP-адрес и порт
localAddr, err := net.ResolveUDPAddr("udp", "127.0.0.1:0")
if err != nil {
log.Fatal(err)
}
// установка соединения
conn, err := net.DialUDP("udp", localAddr, serverAddr)
if err != nil {
log.Fatal(err)
}
// отложенное закрытие соединения
defer conn.Close()
for {
// получение данных от ВЕРХНЕГО уровня
fmt.Print("Введите строчное предложение > ")
var msg string
_, err := fmt.Scanf("%s", &msg)
if err != nil {
log.Fatal(err)
}
// передается поток байт, а не строка
buf := []byte(msg)
// запись (передача) в соединение
_, err = conn.Write(buf)
if err != nil {
log.Fatal(err)
}
// 1 секундочку
time.Sleep(time.Second * 1)
}
}Trosglwyddo data dibynadwy dros sianel gyda gwallau posibl
Y cam nesaf yw tybio bod yr holl becynnau a drosglwyddir yn cael eu derbyn yn y drefn y cawsant eu hanfon, ond gall y darnau ynddynt gael eu llygru oherwydd bod y sianel weithiau'n trosglwyddo data gydag ystumiadau.

Yn yr achos hwn, defnyddir y mecanweithiau canlynol:
- canfod gwallau;
- adborth;
- ail-drosglwyddo.
Gelwir protocolau trosglwyddo data dibynadwy sydd â mecanweithiau tebyg ar gyfer ailadrodd trawsyrru sawl gwaith yn brotocolau Awtomatig Repeat ReQuest (ARQ).
Yn ogystal, mae'n werth ystyried y posibilrwydd o wallau mewn derbynebau, pan na fydd y parti sy'n derbyn yn derbyn unrhyw wybodaeth am ganlyniadau trosglwyddo'r pecyn olaf.
Yr ateb i'r broblem hon, a ddefnyddir hefyd yn TCP, yw ychwanegu maes newydd at y pecyn data sy'n cynnwys rhif dilyniant y pecyn.

Trosglwyddiad data dibynadwy dros sianel annibynadwy yn amodol ar ystumio a cholli pecynnau
Ynghyd ag afluniad, yn anffodus, mae colled pecynnau yn y rhwydwaith.
Ac i ddatrys y broblem hon, mae angen mecanweithiau:
- pennu'r ffaith bod pecynnau'n cael eu colli;
- ail-ddosbarthu pecynnau coll i'r parti sy'n derbyn.
Yn ogystal, yn ogystal â cholli'r pecyn, mae angen darparu ar gyfer y posibilrwydd o golli derbynneb neu, os na chaiff unrhyw beth ei golli, ei gyflwyno gydag oedi sylweddol. Ym mhob achos, gwneir yr un peth: ail-drosglwyddo'r pecyn. Er mwyn rheoli amser, mae'r mecanwaith hwn yn defnyddio amserydd cyfrif i lawr, sy'n eich galluogi i bennu diwedd yr egwyl aros. Felly yn y pecyn Mae TCPKeepAlive wedi'i osod i 15 eiliad yn ddiofyn:
// defaultTCPKeepAlive is a default constant value for TCPKeepAlive times
// See golang.org/issue/31510
const (
defaultTCPKeepAlive = 15 * time.Second
)Mae angen i'r ochr anfon gychwyn amserydd bob tro y caiff pecyn ei drosglwyddo (y tro cyntaf a'r ail dro), trin amhariadau o'r amserydd a'i atal.
Felly, rydym wedi dod yn gyfarwydd â chysyniadau allweddol protocolau trosglwyddo data dibynadwy:
- sieciau;
- dilyniant niferoedd pecynnau;
- amseryddion;
- derbyniadau cadarnhaol a negyddol.
Ond nid dyna'r cyfan!
Protocol trosglwyddo data dibynadwy gyda phiblinellau
Yn yr amrywiad yr ydym eisoes wedi’i ystyried, mae’r protocol cyflenwi dibynadwy yn aneffeithlon iawn. Mae'n dechrau “arafu” y trosglwyddiad a ddarperir gan y sianel gyfathrebu wrth i'r RTT gynyddu. Er mwyn cynyddu ei effeithlonrwydd a gwneud defnydd gwell o gapasiti'r sianel gyfathrebu, defnyddir pibellau.

Mae defnyddio pibellau yn arwain at:
- cynyddu'r ystod o rifau dilyniant, gan fod yn rhaid i'r holl becynnau a anfonir (ac eithrio ailddarllediadau) gael eu hadnabod yn unigryw;
- yr angen i gynyddu byfferau ar yr ochrau trosglwyddo a derbyn.
Mae ystod rhif dilyniant a gofynion maint byffer yn dibynnu ar y camau y mae'r protocol yn eu cymryd mewn ymateb i lygredd pecyn, colled ac oedi. Yn achos pibellau, mae dau ddull ar gyfer cywiro gwallau:
- dychwelyd pecynnau N yn ôl;
- ailadrodd detholus.
Mynd yn ôl N pecynnau - protocol ffenestr llithro

Rhaid i'r anfonwr gefnogi tri math o ddigwyddiad:
- galwad trwy brotocol lefel uwch. Pan elwir y swyddogaeth anfon data yn “o'r uchod”, mae'r ochr anfon yn gyntaf yn gwirio i ba raddau y mae'r ffenestr wedi'i llenwi (hynny yw, presenoldeb N negeseuon a anfonwyd yn aros am dderbynebau). Os yw'r ffenestr yn wag, mae pecyn newydd yn cael ei gynhyrchu a'i drosglwyddo, ac mae'r gwerthoedd newidiol yn cael eu diweddaru. Fel arall, mae'r ochr anfon yn dychwelyd data i'r haen uchaf, ac mae hyn yn arwydd ymhlyg bod y ffenestr yn llawn. Yn nodweddiadol bydd yr haen uchaf yn ceisio trosglwyddo'r data eto ar ôl peth amser. Mewn cymhwysiad go iawn, mae'n debyg y byddai'r anfonwr naill ai'n clustogi'r data (yn lle ei anfon ar unwaith) neu'n meddu ar fecanwaith cydamseru (fel semaffor neu faner) a fyddai'n caniatáu i'r haen uchaf alw'r swyddogaeth anfon dim ond pan fydd y ffenestr yn wag .
- derbyn cadarnhad. Yn y protocol, ar gyfer pecyn gyda rhif dilyniant N, rhoddir cydnabyddiaeth gyffredinol yn nodi bod yr holl becynnau gyda rhifau dilyniant cyn N wedi'u derbyn yn llwyddiannus.
- mae'r cyfnod aros wedi dod i ben. Er mwyn pennu ffeithiau colledion ac oedi o ran pecynnau a derbynebau, mae'r protocol yn defnyddio amserydd. Os daw'r cyfnod terfyn amser i ben, bydd yr ochr anfon yn ail-anfon yr holl becynnau heb eu cydnabod a anfonwyd.
Ailadrodd detholus
Pan fydd maint y ffenestr a'r cynnyrch oedi trwygyrch yn fawr, efallai y bydd nifer fawr o becynnau ar y gweill. Mewn achos o'r fath, gall gwall pecyn sengl achosi i nifer fawr o becynnau gael eu hail-drosglwyddo, ac nid oedd angen y rhan fwyaf ohonynt.
Enghraifft
Top cesglir arferion mewn gweithrediad ymarferol . Ac os oes rhywun yn gwybod sut orau - .
Gweinydd
package main
import (
"bufio"
"fmt"
"log"
"net"
"strings"
)
func main() {
// создаем сокет с портом
ln, err := net.Listen("tcp", ":8081")
if err != nil {
log.Fatalln(err)
}
// ожидание вызова
conn, _ := ln.Accept()
for {
// считывание данных
msg, err := bufio.NewReader(conn).ReadString('n')
if err != nil {
log.Fatalln(err)
}
// вывод сообщения в stdout
fmt.Print("Message Received:", string(msg))
// перевод строки в верхний регистр
newMsg := strings.ToUpper(msg)
// отправка данных
conn.Write([]byte(newMsg + "n"))
}
}Cwsmer
package main
import (
"bufio"
"fmt"
"log"
"net"
"os"
)
func main() {
// установка соединения
conn, err := net.Dial("tcp", "127.0.0.1:8081")
if err != nil {
log.Fatalln(err)
}
for {
// считывание данных с stdin
reader := bufio.NewReader(os.Stdin)
fmt.Print("Text to send: ")
// построчно
text, err := reader.ReadString('n')
if err != nil {
log.Fatalln(err)
}
// отправка
fmt.Fprintf(conn, text+"n")
// прием
msg, err := bufio.NewReader(conn).ReadString('n')
if err != nil {
log.Fatalln(err)
}
// вывод полученного ответа
fmt.Print("Msg from Server: " + msg)
}
}Allbwn
Mecanweithiau i sicrhau bod data'n cael ei drosglwyddo a'i ddefnyddio'n ddibynadwy
Mecanwaith
Cais, sylw
Gwirio swm
Fe'i defnyddir i ganfod gwallau didau mewn pecyn a drosglwyddir
Amserydd
Yn cyfrif yr egwyl terfyn amser ac yn nodi pryd y mae wedi dod i ben. Mae'r olaf yn golygu, gyda lefel uchel o debygolrwydd, y bydd y pecyn neu'r derbynneb yn cael ei golli wrth ei drosglwyddo. Os caiff pecyn ei ddosbarthu gydag oedi, ond nad yw'n cael ei golli (cyfnod terfyn amser yn dod i ben yn gynnar), neu os collir derbynneb, mae aildrosglwyddo yn arwain at becyn dyblyg ar yr ochr dderbyn
Rhif Serial
Fe'i defnyddir ar gyfer rhifo pecynnau data a drosglwyddir o'r anfonwr i'r derbynnydd yn olynol. Mae bylchau yn niferoedd dilyniant y pecynnau a dderbyniwyd yn caniatáu i'r derbynnydd ganfod colled pecyn. Mae'r un rhifau dilyniant pecynnau yn golygu bod y pecynnau yn ddyblyg o'i gilydd
Cadarnhad
Wedi'i gynhyrchu gan y diwedd derbyn ac yn nodi i'r diwedd anfon bod y pecyn neu'r grŵp cyfatebol o becynnau wedi'u derbyn yn llwyddiannus. Yn nodweddiadol, mae'r gydnabyddiaeth yn cynnwys dilyniant y pecynnau a dderbyniwyd yn llwyddiannus. Yn dibynnu ar y protocol, gwahaniaethir cadarnhad unigol a grŵp
Cadarnhad negyddol
Defnyddir gan y derbynnydd i hysbysu'r anfonwr bod y pecyn wedi'i dderbyn yn anghywir. Mae cydnabyddiaeth negyddol fel arfer yn cynnwys rhif dilyniant y pecyn na chafodd ei dderbyn yn gywir
Ffenestr, cludiad
Cyfyngu ar yr ystod o rifau dilyniant y gellir eu defnyddio i drawsyrru pecynnau. Gall aml-ddarllediad ac ysgwyd llaw gynyddu trwybwn protocol yn sylweddol o gymharu ag aros am gydnabyddiaeth. Fel y gwelwn, gellir cyfrifo maint y ffenestr yn seiliedig ar alluoedd derbyn a byffro y pen derbyn, yn ogystal â lefel llwyth y rhwydwaith
Mwy o enghreifftiau o ddefnyddio Go ar gyfer rhwydweithio
В .
Ffynhonnell: hab.com
