කරන අයට
කෙටියෙන්
ලිපිය විශ්වාසදායක දත්ත සම්ප්රේෂණයේ මූලික කරුණු සාකච්ඡා කරයි, උදාහරණ ක්රියාත්මක කරයි
ප්රවාහන ස්ථර ප්රොටෝකෝලය
විවිධ ධාරක මත ක්රියාත්මක වන යෙදුම් ක්රියාවලි අතර තාර්කික සම්බන්ධතාවයක් සපයයි. යෙදුම් දෘෂ්ටිකෝණයකින්, තාර්කික සම්බන්ධතාවයක් ක්රියාවලි සෘජුවම සම්බන්ධ කරන නාලිකාවක් ලෙස පෙනේ.
මෙය සිදු කරනු ලබන්නේ (අවශ්ය නම්) යෙදුම් ස්ථර පණිවිඩ කැබලිවලට බෙදීම සහ ඒ සෑම එකක් සඳහාම ප්රවාහන ස්ථර ශීර්ෂයක් එක් කිරීමෙනි.
එවිට ප්රවාහන ස්තරය එම කොටස යවන්නාගේ ජාල ස්තරය වෙත යවයි, එහිදී එම කොටස ජාල ස්ථර පැකට්ටුවක (දත්ත ග්රෑම්) කොටු කර යවනු ලැබේ. ලැබීමේ කෙළවරේ, ජාල ස්තරය දත්ත ග්රෑම් එකෙන් ප්රවාහන ස්ථර කොටස උපුටා ගෙන එය ප්රවාහන ස්තරය දක්වා ගමන් කරයි. ඊළඟට, ප්රවාහන ස්තරය ලැබුණු කොටස සකසන අතර එමඟින් එහි දත්ත ලැබෙන යෙදුමට ලබා ගත හැකිය.
විශ්වසනීය දත්ත සම්ප්රේෂණයේ මූලධර්ම
සම්පූර්ණයෙන්ම ආරක්ෂිත නාලිකාවක් හරහා විශ්වසනීය දත්ත සම්ප්රේෂණය
සරලම නඩුව. යවන පැත්ත සරලව ඉහළ ස්ථරයෙන් දත්ත ලබා ගනී, එය අඩංගු පැකට්ටුවක් සාදා එය නාලිකාවට යවයි.
සර්වර්
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 ට පෙර අනුක්රමික අංක සහිත සියලුම පැකට් සාර්ථකව ලැබුණු බවට සාමාන්ය පිළිගැනීමක් නිකුත් කෙරේ.
- පොරොත්තු කාල සීමාව අවසන් වී ඇත. පැකට් සහ රිසිට්පත් වල පාඩු සහ ප්රමාදයන් පිළිබඳ කරුණු තීරණය කිරීම සඳහා, ප්රොටෝකෝලය ටයිමරයක් භාවිතා කරයි. කල් ඉකුත් වීමේ කාල පරතරය කල් ඉකුත් වුවහොත්, යවන පැත්ත යවන ලද සියලුම නොපිළිගත් පැකට් නැවත යවයි.
වරණීය පුනරාවර්තනය
කවුළු ප්රමාණය සහ ප්රචාරණ ප්රමාද නිෂ්පාදනය විශාල වන විට, පැකට් විශාල ප්රමාණයක් නල මාර්ගයේ තිබිය හැක. එවැනි අවස්ථාවක, එක් පැකට් දෝෂයක් නිසා පැකට් විශාල ප්රමාණයක් නැවත සම්ප්රේෂණය වීමට ඉඩ ඇති අතර, ඒවායින් බොහොමයක් අවශ්ය නොවීය.
උදාහරණ:
හොඳම දේ
සර්වර්
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)
}
}
නිගමනය
විශ්වසනීය දත්ත හුවමාරුව සහ භාවිතය සහතික කිරීම සඳහා යාන්ත්රණ
යාන්ත්රණය
යෙදුම, අදහස් දැක්වීම
එකතුව පරීක්ෂා කරන්න
සම්ප්රේෂණය කරන ලද පැකට්ටුවක බිට් දෝෂ හඳුනා ගැනීමට භාවිතා කරයි
ටයිමර්
කල් ඉකුත් වූ කාල පරතරය ගණන් කරන අතර එය කල් ඉකුත් වූ විට දක්වයි. දෙවැන්නෙන් අදහස් කරන්නේ සම්භාවිතාවේ ඉහළ මට්ටමක පැකට්ටුව හෝ එහි රිසිට්පත සම්ප්රේෂණය කිරීමේදී නැති වී යන බවයි. පැකට්ටුවක් ප්රමාදයකින් බෙදා හරිනු ලැබුවද, නැතිවී නොගියහොත් (කාල සීමාවේ කාල සීමාව අකාලයේ කල් ඉකුත්වීම) හෝ රිසිට්පතක් නැති වුවහොත්, නැවත සම්ප්රේෂණය ලබන පැත්තේ අනුපිටපත් පැකට්ටුවකට යොමු කරයි.
අන්රක්රමික අංකය
යවන්නාගේ සිට ලබන්නා දක්වා සම්ප්රේෂණය වන දත්ත පැකට් අනුක්රමික අංක කිරීම සඳහා භාවිත කෙරේ. ලැබුණු පැකට් වල අනුක්රමික අංකවල හිඩැස් ග්රාහකයාට පැකට් නැතිවීම හඳුනා ගැනීමට ඉඩ සලසයි. එකම පැකට් අනුක්රමික අංක වලින් අදහස් වන්නේ පැකට් එකිනෙක අනුපිටපත් බවයි
තහවුරු කිරීම
ලැබීමේ අන්තය මගින් උත්පාදනය කර ඇති අතර අනුරූප පැකට්ටුව හෝ පැකට් සමූහය සාර්ථකව ලැබී ඇති බව යැවීමේ අන්තයට දක්වයි. සාමාන්යයෙන් පිළිගැනීමේ සාර්ථක ලෙස ලැබුණු පැකට් වල අනුක්රමික අංක අඩංගු වේ. ප්රොටෝකෝලය මත පදනම්ව, පුද්ගල සහ කණ්ඩායම් තහවුරු කිරීම් වෙන්කර හඳුනාගත හැකිය
සෘණ තහවුරු කිරීම
පැකට්ටුව වැරදි ලෙස ලැබුණු බව යවන්නාට දැනුම් දීමට ලබන්නා විසින් භාවිතා කරයි. ඍණාත්මක පිළිගැනීමකට සාමාන්යයෙන් ඇතුළත් වන්නේ නිවැරදිව නොලැබුණු පැකට්ටුවේ අනුක්රමික අංකයයි
කවුළුව, වාහකකරණය
පැකට් සම්ප්රේෂණය කිරීමට භාවිතා කළ හැකි අනුක්රමික අංක පරාසය සීමා කරන්න. Multicast සහ handshake පිළිගැනීම් සඳහා බලා සිටීම හා සසඳන විට ප්රොටෝකෝල ප්රතිදානය සැලකිය යුතු ලෙස වැඩි කළ හැක. අප දකින පරිදි, ලැබීමේ කෙළවරේ පිළිගැනීමේ සහ බෆරින් කිරීමේ හැකියාවන් මෙන්ම ජාල භාර මට්ටම මත පදනම්ව කවුළු ප්රමාණය ගණනය කළ හැකිය.
ජාලකරණය සඳහා Go භාවිතා කිරීමේ තවත් උදාහරණ
В
මූලාශ්රය: www.habr.com