ఉన్న వారికి
క్లుప్తంగా
కథనం నమ్మదగిన డేటా ట్రాన్స్మిషన్ యొక్క ప్రాథమికాలను చర్చిస్తుంది, ఉదాహరణలను అమలు చేస్తుంది
రవాణా పొర ప్రోటోకాల్
వివిధ హోస్ట్లలో అమలవుతున్న అప్లికేషన్ ప్రాసెస్ల మధ్య లాజికల్ కనెక్షన్ని అందిస్తుంది. అనువర్తన దృక్కోణం నుండి, లాజికల్ కనెక్షన్ ప్రక్రియలను నేరుగా కనెక్ట్ చేసే ఛానెల్ వలె కనిపిస్తుంది.
అప్లికేషన్ లేయర్ సందేశాలను శకలాలుగా విభజించి (అవసరమైతే) మరియు వాటిలో ప్రతిదానికి రవాణా లేయర్ హెడర్ను జోడించడం ద్వారా ఇది జరుగుతుంది.
ట్రాన్స్పోర్ట్ లేయర్ సెగ్మెంట్ను పంపినవారి నెట్వర్క్ లేయర్కు పంపుతుంది, ఇక్కడ సెగ్మెంట్ నెట్వర్క్ లేయర్ ప్యాకెట్ (డేటాగ్రామ్)లో కప్పబడి పంపబడుతుంది. స్వీకరించే ముగింపులో, నెట్వర్క్ లేయర్ డేటాగ్రామ్ నుండి ట్రాన్స్పోర్ట్ లేయర్ సెగ్మెంట్ను సంగ్రహిస్తుంది మరియు దానిని ట్రాన్స్పోర్ట్ లేయర్కు పంపుతుంది. తరువాత, రవాణా పొర అందుకున్న విభాగాన్ని ప్రాసెస్ చేస్తుంది, తద్వారా దాని డేటా స్వీకరించే అప్లికేషన్కు అందుబాటులో ఉంటుంది.
విశ్వసనీయ సమాచార ప్రసారం యొక్క సూత్రాలు
పూర్తిగా సురక్షితమైన ఛానెల్ ద్వారా విశ్వసనీయమైన డేటా ట్రాన్స్మిషన్
సరళమైన కేసు. పంపే వైపు కేవలం ఎగువ పొర నుండి డేటాను స్వీకరిస్తుంది, దానిని కలిగి ఉన్న ప్యాకెట్ను సృష్టించి, దానిని ఛానెల్కు పంపుతుంది.
సర్వర్
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 + надежный канал
}
}
కస్టమర్
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)
}
}
సంభావ్య లోపాలతో ఛానెల్ ద్వారా విశ్వసనీయ డేటా ప్రసారం
తదుపరి దశ ఏమిటంటే, ప్రసారం చేయబడిన అన్ని ప్యాకెట్లు అవి పంపబడిన క్రమంలో స్వీకరించబడ్డాయి, అయితే ఛానెల్ కొన్నిసార్లు వక్రీకరణలతో డేటాను ప్రసారం చేసే వాస్తవం కారణంగా వాటిలోని బిట్లు పాడైపోవచ్చు.
ఈ సందర్భంలో, కింది యంత్రాంగాలు ఉపయోగించబడతాయి:
- లోపం గుర్తింపు;
- అభిప్రాయం;
- పునఃప్రసారం.
ట్రాన్స్మిషన్ను అనేకసార్లు పునరావృతం చేయడానికి సారూప్య విధానాలను కలిగి ఉన్న విశ్వసనీయ డేటా బదిలీ ప్రోటోకాల్లను ఆటోమేటిక్ రిపీట్ రిక్వెస్ట్ (ARQ) ప్రోటోకాల్లు అంటారు.
అదనంగా, చివరి ప్యాకెట్ యొక్క బదిలీ ఫలితాల గురించి స్వీకరించే పార్టీ ఎటువంటి సమాచారాన్ని అందుకోనప్పుడు, రసీదులలో లోపాల సంభావ్యతను పరిగణనలోకి తీసుకోవడం విలువ.
ఈ సమస్యకు పరిష్కారం, TCPలో కూడా ఉపయోగించబడుతుంది, ప్యాకెట్ సీక్వెన్స్ నంబర్ను కలిగి ఉన్న డేటా ప్యాకెట్కు కొత్త ఫీల్డ్ను జోడించడం.
ప్యాకెట్ వక్రీకరణ మరియు నష్టానికి లోబడి నమ్మదగని ఛానెల్ ద్వారా విశ్వసనీయ డేటా ప్రసారం
వక్రీకరణతో పాటు, దురదృష్టవశాత్తు, నెట్వర్క్లో ప్యాకెట్ నష్టం ఉంది.
మరియు ఈ సమస్యను పరిష్కరించడానికి, యంత్రాంగాలు అవసరం:
- ప్యాకెట్ నష్టం యొక్క వాస్తవాన్ని నిర్ణయించడం;
- కోల్పోయిన ప్యాకెట్లను స్వీకరించే పార్టీకి తిరిగి డెలివరీ చేయడం.
అదనంగా, ప్యాకేజీ యొక్క నష్టానికి అదనంగా, రసీదుని కోల్పోయే అవకాశం లేదా ఏమీ కోల్పోకపోతే, గణనీయమైన ఆలస్యంతో దాని డెలివరీని అందించడం అవసరం. అన్ని సందర్భాల్లో, అదే పని చేయబడుతుంది: ప్యాకెట్ తిరిగి ప్రసారం చేయబడుతుంది. సమయాన్ని నియంత్రించడానికి, ఈ మెకానిజం కౌంట్డౌన్ టైమర్ను ఉపయోగిస్తుంది, ఇది నిరీక్షణ విరామం ముగింపును నిర్ణయించడానికి మిమ్మల్ని అనుమతిస్తుంది. కాబట్టి ప్యాకేజీలో
// defaultTCPKeepAlive is a default constant value for TCPKeepAlive times
// See golang.org/issue/31510
const (
defaultTCPKeepAlive = 15 * time.Second
)
పంపే వైపు ప్యాకెట్ ప్రసారం చేయబడిన ప్రతిసారీ టైమర్ను ప్రారంభించాలి (మొదటి మరియు రెండవ సారి), టైమర్ నుండి అంతరాయాలను నిర్వహించి, దాన్ని ఆపండి.
కాబట్టి, విశ్వసనీయ డేటా బదిలీ ప్రోటోకాల్ల యొక్క ముఖ్య భావనలతో మేము సుపరిచితం అయ్యాము:
- చెక్సమ్లు;
- ప్యాకేజీల వరుస సంఖ్యలు;
- టైమర్లు;
- సానుకూల మరియు ప్రతికూల రసీదులు.
అయితే అంతే కాదు!
పైప్లైనింగ్తో విశ్వసనీయ డేటా బదిలీ ప్రోటోకాల్
మేము ఇప్పటికే పరిగణించిన వేరియంట్లో, నమ్మదగిన డెలివరీ ప్రోటోకాల్ చాలా అసమర్థంగా ఉంది. ఇది RTT పెరిగేకొద్దీ కమ్యూనికేషన్ ఛానెల్ అందించిన ప్రసారాన్ని "నెమ్మదిగా" ప్రారంభమవుతుంది. దాని సామర్థ్యాన్ని పెంచడానికి మరియు కమ్యూనికేషన్ ఛానల్ సామర్థ్యాన్ని బాగా ఉపయోగించుకోవడానికి, పైప్లైన్ ఉపయోగించబడుతుంది.
పైప్లైన్ వాడకం దీనికి దారితీస్తుంది:
- క్రమ సంఖ్యల పరిధిని పెంచడం, పంపిన అన్ని ప్యాకెట్లు (పునర్ప్రసారాలు మినహా) ప్రత్యేకంగా గుర్తించబడాలి;
- ప్రసారం మరియు స్వీకరించే వైపులా బఫర్లను పెంచాల్సిన అవసరం ఉంది.
సీక్వెన్స్ నంబర్ పరిధి మరియు బఫర్ పరిమాణం అవసరాలు ప్యాకెట్ అవినీతి, నష్టం మరియు ఆలస్యానికి ప్రతిస్పందనగా ప్రోటోకాల్ తీసుకునే చర్యలపై ఆధారపడి ఉంటాయి. పైప్లైన్ విషయంలో, లోపాలను సరిచేయడానికి రెండు పద్ధతులు ఉన్నాయి:
- తిరిగి N ప్యాకెట్లు;
- ఎంపిక పునరావృతం.
N ప్యాకెట్లు వెనుకకు వెళ్లడం - స్లైడింగ్ విండో ప్రోటోకాల్
పంపినవారు తప్పనిసరిగా మూడు రకాల ఈవెంట్లకు మద్దతు ఇవ్వాలి:
- ఉన్నత స్థాయి ప్రోటోకాల్ ద్వారా కాల్ చేయండి. డేటా పంపే ఫంక్షన్ను “పై నుండి” అని పిలిచినప్పుడు, పంపే వైపు మొదట విండోను నింపే స్థాయిని తనిఖీ చేస్తుంది (అనగా, రసీదుల రసీదు కోసం N పంపిన సందేశాల ఉనికి). విండో ఖాళీగా ఉంటే, కొత్త ప్యాకెట్ ఉత్పత్తి చేయబడుతుంది మరియు ప్రసారం చేయబడుతుంది మరియు వేరియబుల్ విలువలు నవీకరించబడతాయి. లేకపోతే, పంపే వైపు డేటా ఎగువ పొరకు తిరిగి వస్తుంది మరియు ఇది విండో నిండినట్లు అవ్యక్త సూచన. సాధారణంగా ఎగువ పొర కొంత సమయం తర్వాత మళ్లీ డేటాను ప్రసారం చేయడానికి ప్రయత్నిస్తుంది. నిజమైన అప్లికేషన్లో, పంపినవారు డేటాను బఫర్ చేయవచ్చు (వెంటనే పంపే బదులు) లేదా సింక్రొనైజేషన్ మెకానిజం (సెమాఫోర్ లేదా ఫ్లాగ్ వంటివి) కలిగి ఉండవచ్చు, ఇది విండో ఖాళీగా ఉన్నప్పుడు మాత్రమే పంపే ఫంక్షన్కి కాల్ చేయడానికి ఎగువ పొరను అనుమతిస్తుంది. .
- నిర్ధారణను స్వీకరించడం. ప్రోటోకాల్లో, సీక్వెన్స్ నంబర్ N ఉన్న ప్యాకెట్ కోసం, N కంటే ముందు వరుస సంఖ్యలు ఉన్న అన్ని ప్యాకెట్లు విజయవంతంగా స్వీకరించబడినట్లు సూచించే సాధారణ రసీదు జారీ చేయబడుతుంది.
- నిరీక్షణ విరామం గడువు ముగిసింది. ప్యాకెట్లు మరియు రసీదుల నష్టాలు మరియు జాప్యాల వాస్తవాలను గుర్తించడానికి, ప్రోటోకాల్ టైమర్ను ఉపయోగిస్తుంది. గడువు ముగింపు వ్యవధి ముగిసిపోతే, పంపిన వైపు పంపిన అన్ని గుర్తించబడని ప్యాకెట్లను మళ్లీ పంపుతుంది.
ఎంపిక పునరావృతం
విండో పరిమాణం మరియు నిర్గమాంశ-ప్రచారం ఆలస్యం ఉత్పత్తి పెద్దగా ఉన్నప్పుడు, పెద్ద సంఖ్యలో ప్యాకెట్లు పైప్లైన్లో ఉండవచ్చు. అటువంటి సందర్భంలో, ఒక ప్యాకెట్ లోపం పెద్ద సంఖ్యలో ప్యాకెట్లను తిరిగి ప్రసారం చేయడానికి కారణం కావచ్చు, వీటిలో చాలా వరకు అవసరం లేదు.
ఉదాహరణకు
Лучшие
సర్వర్
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"))
}
}
కస్టమర్
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)
}
}
తీర్మానం
విశ్వసనీయ డేటా బదిలీ మరియు వినియోగాన్ని నిర్ధారించడానికి మెకానిజమ్స్
విధానం
అప్లికేషన్, వ్యాఖ్య
మొత్తాన్ని తనిఖీ చేయండి
ప్రసారం చేయబడిన ప్యాకెట్లో బిట్ లోపాలను గుర్తించడానికి ఉపయోగించబడుతుంది
టైమర్
సమయం ముగిసిన విరామాన్ని గణిస్తుంది మరియు గడువు ముగిసినప్పుడు సూచిస్తుంది. రెండోది అంటే అధిక స్థాయి సంభావ్యతతో ప్యాకెట్ లేదా దాని రసీదు ప్రసార సమయంలో పోతుంది. ఒక ప్యాకెట్ ఆలస్యంతో డెలివరీ చేయబడి, కోల్పోకపోతే (సమయం ముగిసిన విరామం యొక్క అకాల గడువు), లేదా రసీదు పోయినట్లయితే, పునఃప్రసారం స్వీకరించే వైపు నకిలీ ప్యాకెట్కు దారి తీస్తుంది
క్రమ సంఖ్య
పంపినవారి నుండి గ్రహీతకు బదిలీ చేయబడిన డేటా ప్యాకెట్ల వరుస సంఖ్యల కోసం ఉపయోగించబడుతుంది. అందుకున్న ప్యాకెట్ల సీక్వెన్స్ నంబర్లలోని ఖాళీలు ప్యాకెట్ నష్టాన్ని గుర్తించడానికి రిసీవర్ని అనుమతిస్తాయి. అదే ప్యాకెట్ సీక్వెన్స్ నంబర్లు అంటే ప్యాకెట్లు ఒకదానికొకటి నకిలీలు
నిర్ధారణ
స్వీకరించే ముగింపు ద్వారా రూపొందించబడింది మరియు సంబంధిత ప్యాకెట్ లేదా ప్యాకెట్ల సమూహం విజయవంతంగా స్వీకరించబడిందని పంపే ముగింపుకు సూచిస్తుంది. సాధారణంగా రసీదు విజయవంతంగా అందుకున్న ప్యాకెట్ల క్రమ సంఖ్యలను కలిగి ఉంటుంది. ప్రోటోకాల్పై ఆధారపడి, వ్యక్తిగత మరియు సమూహ నిర్ధారణలు వేరు చేయబడతాయి
ప్రతికూల నిర్ధారణ
ప్యాకెట్ తప్పుగా స్వీకరించబడిందని పంపినవారికి తెలియజేయడానికి గ్రహీత ఉపయోగించబడుతుంది. ప్రతికూల రసీదు సాధారణంగా సరిగ్గా అందుకోని ప్యాకెట్ సీక్వెన్స్ నంబర్ను కలిగి ఉంటుంది
విండో, కన్వేయరైజేషన్
ప్యాకెట్లను ప్రసారం చేయడానికి ఉపయోగించే క్రమ సంఖ్యల పరిధిని పరిమితం చేయండి. రసీదుల కోసం వేచి ఉండటంతో పోలిస్తే మల్టీకాస్ట్ మరియు హ్యాండ్షేక్ ప్రోటోకాల్ నిర్గమాంశను గణనీయంగా పెంచుతుంది. మేము చూడబోతున్నట్లుగా, స్వీకరించే ముగింపు యొక్క రిసెప్షన్ మరియు బఫరింగ్ సామర్థ్యాలు, అలాగే నెట్వర్క్ లోడ్ స్థాయి ఆధారంగా విండో పరిమాణాన్ని లెక్కించవచ్చు.
నెట్వర్కింగ్ కోసం గోను ఉపయోగించే మరిన్ని ఉదాహరణలు
В
మూలం: www.habr.com