இருப்பவர்களுக்கு
சுருக்கமாக
கட்டுரை நம்பகமான தரவு பரிமாற்றத்தின் அடிப்படைகளை விவாதிக்கிறது, எடுத்துக்காட்டுகளை செயல்படுத்துகிறது
போக்குவரத்து அடுக்கு நெறிமுறை
வெவ்வேறு ஹோஸ்ட்களில் இயங்கும் பயன்பாட்டு செயல்முறைகளுக்கு இடையே தருக்க இணைப்பை வழங்குகிறது. பயன்பாடுகளின் பார்வையில் இருந்து ஒரு தருக்க இணைப்பு செயல்முறைகளை நேரடியாக இணைக்கும் சேனல் போல் தெரிகிறது.
பயன்பாட்டு லேயர் செய்திகளை துண்டுகளாகப் பிரித்து (தேவைப்பட்டால்) அவை ஒவ்வொன்றிற்கும் ஒரு போக்குவரத்து அடுக்கு தலைப்பைச் சேர்ப்பதன் மூலம் இது செய்யப்படுகிறது.
டிரான்ஸ்போர்ட் லேயர் அந்த பிரிவை அனுப்புநரின் நெட்வொர்க் லேயருக்கு அனுப்புகிறது, அங்கு அந்த பிரிவு நெட்வொர்க் லேயர் பாக்கெட்டில் (டேட்டாகிராம்) இணைக்கப்பட்டு வெளியே அனுப்பப்படுகிறது. பெறும் பக்கத்தில், நெட்வொர்க் லேயர் டேட்டாகிராமில் இருந்து டிரான்ஸ்போர்ட் லேயர் பிரிவை பிரித்தெடுத்து, அதை டிரான்ஸ்போர்ட் லேயருக்கு அனுப்புகிறது. அடுத்து, போக்குவரத்து அடுக்கு பெறப்பட்ட பிரிவை செயலாக்குகிறது, அதன் தரவு பெறும் பயன்பாட்டிற்கு கிடைக்கும்.
நம்பகமான தரவு பரிமாற்றத்தின் கோட்பாடுகள்
முற்றிலும் நம்பகமான சேனலில் நம்பகமான தரவு பரிமாற்றம்
எளிமையான வழக்கு. அனுப்புநர் மேல் அடுக்கிலிருந்து தரவைப் பெற்று, அதைக் கொண்ட ஒரு பாக்கெட்டை உருவாக்கி, சேனலுக்கு அனுப்புவார்.
Сервер
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)
}
}
முடிவுக்கு
நம்பகமான தரவு பரிமாற்றம் மற்றும் பயன்பாட்டை உறுதி செய்வதற்கான வழிமுறைகள்
பொறிமுறையை
விண்ணப்பம், கருத்து
தொகையை சரிபார்க்கவும்
கடத்தப்பட்ட பாக்கெட்டில் பிட் பிழைகளைக் கண்டறியப் பயன்படுகிறது.
டைமர்
காத்திருக்கும் இடைவெளியின் கவுண்டவுன் மற்றும் அதன் காலாவதிக்கான அறிகுறி. பிந்தையது, அதிக அளவு நிகழ்தகவுடன் தொகுப்பு அல்லது அதன் ரசீது பரிமாற்றத்தின் போது இழக்கப்படுகிறது. பாக்கெட் தாமதத்துடன் டெலிவரி செய்யப்பட்டாலும், தொலைந்து போகவில்லை என்றால் (காத்திருப்பு இடைவெளியின் முன்கூட்டிய காலாவதி), அல்லது ரசீது தொலைந்துவிட்டால், மறுபரிமாற்றம் பாக்கெட்டை பெறும் பக்கத்தில் நகலெடுக்க வழிவகுக்கிறது.
வரிசை எண்
அனுப்புநரிடமிருந்து பெறுநருக்கு அனுப்பப்படும் தரவு பாக்கெட்டுகளின் வரிசை எண்களுக்குப் பயன்படுத்தப்படுகிறது. பெறப்பட்ட பாக்கெட்டுகளின் வரிசை எண்களில் ஏற்படும் முறிவுகள், பெறுநரை பாக்கெட் இழப்பைக் கண்டறிய அனுமதிக்கிறது. அதே பாக்கெட் வரிசை எண்கள் பாக்கெட்டுகள் ஒன்றுக்கொன்று நகல் என்று அர்த்தம்.
உறுதிப்படுத்தல்
பெறும் பக்கத்தால் உருவாக்கப்பட்ட மற்றும் தொடர்புடைய பாக்கெட் அல்லது பாக்கெட்டுகளின் குழு வெற்றிகரமாக பெறப்பட்டதை கடத்தும் பக்கத்திற்கு குறிக்கிறது. பொதுவாக, ஒப்புகையில் வெற்றிகரமாகப் பெற்ற பாக்கெட்டுகளின் வரிசை எண்கள் இருக்கும். நெறிமுறையைப் பொறுத்து, தனிப்பட்ட மற்றும் குழு உறுதிப்படுத்தல்கள் வேறுபடுகின்றன.
எதிர்மறை உறுதிப்படுத்தல்
பாக்கெட் தவறாகப் பெறப்பட்டதாக அனுப்புநருக்குத் தெரிவிக்க பெறுநரால் பயன்படுத்தப்படுகிறது. எதிர்மறை ஒப்புதலில் பொதுவாக சரியாகப் பெறப்படாத பாக்கெட்டின் வரிசை எண் அடங்கும்.
ஜன்னல், குழாய்
பாக்கெட்டுகளை அனுப்பப் பயன்படுத்தக்கூடிய வரிசை எண்களின் வரம்பை வரம்பிடவும். மல்டிகாஸ்ட் மற்றும் ஹேண்ட்ஷேக் ஆகியவை ஒப்புகை காத்திருப்பு பயன்முறையுடன் ஒப்பிடும்போது நெறிமுறைகளின் செயல்திறனை கணிசமாக அதிகரிக்கும். நாம் பார்ப்பது போல், பெறுதல் பக்கத்தின் வரவேற்பு மற்றும் தாங்கல் திறன்கள் மற்றும் நெட்வொர்க் சுமை நிலை ஆகியவற்றின் அடிப்படையில் சாளரத்தின் அளவைக் கணக்கிடலாம்.
நெட்வொர்க்கிங்கிற்கு Go ஐப் பயன்படுத்துவதற்கான பிற எடுத்துக்காட்டுகள்
В
ஆதாரம்: www.habr.com