TCP/IP – лекция за начинаещи

(Допълнена на 10-01-2006.)

Тази лекция не претендира за каквато и да било историческа достоверност – само че е разбираема. Също, конкретиката в нея умишлено е сведена до минимум, за да може човек да се съсредоточи върху принципите.

Предвидена е за хора, които имат някакво понятие какво е файл или операционна система, и горе-долу нищо повече.

Имало едно време… компютър.

Грамаден, и бавен. Единственият, ако не на света, то поне за огромна институция. Можел да изпълнява само по една задача по едно и също време. Нещата вървели, и хората били щастливи.

Появили се обаче т.нар. многозадачни операционни системи – под които могат да работят едновременно няколко програми. Една от тях, т.нар. UNIX, обявила принципа по-сложните действия да се получават от комбинирането на по-прости действия. Съответно, програмите били писани да са прости, а сложните неща да се получават от съвместната им работа, като на конвейер. Една прави първата операция, друга втората, и т.н.

Възникнал обаче въпросът как предишната програма ще предава междинния продукт на следващата. Програмистите предложили просто и изпитано решение – първата програма ще пише във файл, а втората ще чете от него след нея. То работело чудесно, но имало и проблеми. Изписаните междинни файлове заемали ценно дисково място (а тогава то недостигало). Случвало се втората програма да се опита да задмине първата, ако е по-пъргава. И т.н.

За да се решат тези проблеми, бил създаден специален вид файлове – т.нар. pipes (“тръби”, понеже служат за преливане на данни от едно място на друго). За тях било отделяно по съвсем малко място, а по-нататък вече дори не били реални физически файлове на диск, а съществували само “илюзорно”, в паметта на компютъра. Операционната система била натоварена да се грижи за тях – ако първата програма е бърза, и се опита да изпише повече непрочетени данни от отделения лимит, да я задържа временно, и да ускорява втората. А ако втората се опита да задмине първата – да задържа пък нея, и да ускорява първата. Други възможни неприятни ситуации също били предвидени.

Това добре – но всяка програма работела с тези файлове както й падне, и това усложнявало както нейния живот, така и този на операционната система (разбирай – на програмистите, които ги пишат). А понеже програмистите са мързеливи, решили да въведат малко стандартизация, за да си опростят живота.

Били създадени т.нар. номерирани pipes, които да съответстват на стандартни неща. Например номер 0 бил заделен за стандартен вход за данни, 1 – за стандартен изход за данни. 2 бил добавен за стандартен изход за грешки, и т.н. Някои ръководства наричат такива стандартизирани “тръби” sockets (или “муфи”). Муфа номер 1 – за наливане. Муфа номер 2 – за отливане…

Развитието продължавало. Появили се разни приложения като примерно електронна поща. А за нея трябва да има някъде една програма, която да я разпределя – т.нар. сървър. И възникнал въпросът – няма ли някакъв стандартен начин да намираме този сървър някъде, винаги на едно и също място? Ами програмата за точно време? Ами тази за генериране на случайни знаци?…

Проблемът отново бил решен, като използвали вариант на вече утвърдило се нещо – номерираните муфи. Обявили, че ще има известен брой (65535, за любителите на точността) стандартни “муфи”, които ще са едни за цялата машина. Муфа номер 25 примерно ще е за пращане на електронна поща. Номер 13 – за точно време. И т.н. Съответно, сървърът за електронна поща бил “връзван” да чака на муфа 25, този за точно време – на 13… И всички били щастливи. А глобалните за цялата машина “муфи”, за да не бъдат бъркани с другите, били наречени “портове”.

Докато не се появил… вторият компютър. В рамките на институцията.

Веднага, естествено, възникнал въпросът: “Няма ли как да свържем двата, и да си прехвърляме информация между тях”? Има, рекли инженерите. Ей сега ще опънем една жица и ще напоим две устройства за връзка… Опънали, пуснали връзката. Налели от единия край на жицата файл. На другия край обаче той пристигнал с грешки – заради електронните шумове по жицата.

Опитвали се известно време инженерите да направят безшумна линия, но цената се оказала твърде висока. Затова се заели отново програмистите – да търсят начини как да предават данните въпреки шумовете.

Най-напред решили, че ще предадат заедно с файла и някаква контролна сума, и ще я проверят. Ако не съвпада, значи има гаф – ще искаме файла отново… Ако е малък – добре. Но ако е голям, било невъзможно да го предадат без междувременно да влязат шумове. И започнали да мислят как да делят файловете на малки части, и да препоискват всяка от тях при нужда.

Били изпробвани много схеми и начини. Някои се оказали достатъчно добри, за да са използваеми. Една от тях бил създадена от фирмата IBM, и се наричала TCP – Transmission Control Protocol (протокол за контрол на връзката).

При този протокол информацията се предава на малки части – т.нар. пакети. Има различни видове пакети – пакет “Начало на връзка”, пакет “ОК”, пакет “Не разбрах – повтори!”, пакет “Нося данни”, пакет “Край на връзката”, и т.н. Уговорката била, че след всеки пратен пакет (освен “ОК” и “Не разбрах”) се чака пакет “ОК”, или “Не разбрах”, и ако е нужно, пакетът се препраща отново. След още малко уговорки (какво се прави при таймаути, и т.н.), едно примерно прехвърляне на данни започнало да изглежда примерно така:

Начало на връзка ОК
Данни 1 ОК
Данни 2 Не разбрах!
Пак данни 2 ОК
Данни 3 ОК
Край на връзката ОК

Съответно, зад “муфата” за връзка с отсрещния компютър била вградена “софтуерна машина”, която “нарязва” непрекъснатия поток данни на парчета, и ги опакова в TCP пакети – а на отсрещния край, преди “муфата” за получаване, пак подобна машина, която обаче съдира опаковките и слепва парчетата обратно в непрекъснат поток.

Докато между двата компютъра течал само един поток данни, всичко било наред. Но ако текат няколко, как да се разбере за кой е полученият пакет? Решили проблема, като пуснали комуникацията към другата машина през вече утвърдените портове. Всеки поток данни “излизал” от единия компютър през някой порт, и “влизал” в другия през някой порт. А в TCP пакетите вградили освен другото и номерата на изходящия и на входящия порт. Така вече потоците данни не се смесвали.

TCP е това, което се нарича синхронен протокол – след всеки пратен пакет се чака пакет-отговор. Отначало линиите между компютрите били къси и бавни, така че закъсненията в прехвърлянето били пренебрежими. С времето обаче техниката напреднала, линиите станали много по-дълги и по-бързи, и въпреки това по-малко шумни. И времето на пътуване на пакетите започнало да става забележим процент от общото време – тоест, връзката не се използвала пълноценно.

За да се реши този проблем, умни хора решили да не се чака потвърждение след всеки пакет, а само да се препращат отново данни, ако дойде отговор “не получих правилно – дай пак оттук дотук”. Така бил създаден протоколът UDP – пример за асинхронен протокол.

И отново всички били щастливи, докато не се появил… третият компютър.

Кашата в свързването между тях станала пълна. Идва пакет “Начало на връзка” – ама от кой от другите два компютъра? И, всъщност, за мен ли е предназначен, или за този от другите два, който не го е изпратил?… Бъркотия. А как да я оправим, без да развалим нещата, дето досега работеха толкова хубаво?

Нещата били решени, като някой предложил пакетите от други протоколи (примерно TCP или UDP) да се “опаковат” в пакети от нов протокол – т.нар. IP (Internet Protocol). Тези “опаковки” не се грижат за точността на преноса на информацията – вълнуват се от кой и за кой компютър е тя. Съдържат адрес на изпращача, адрес на получателя, пакет от какъв тип протокол е опакован в тях, и още малко подробности. Съответно, пакетиращите и разпакетиращи софтуерни машини били допълнени със още едно звено от конвейера (или “слой” опаковки, ако предпочитате).

Накрая, когато мрежите станали големи и сложни, и компютрите вече не се свързвали пряко помежду си, се появил проблемът с логистиката на пакетите. За да стигне до целта си, вече един пакет трябвало да бъде препращан от междинни компютри. А те пък трябвало да знаят накъде да го пратят.

За тази цел били създадени така наречените routing tables (маршрутни таблици). В тях се описва, простичко казало, за кои IP адреси по коя жица трябва да бъде пратен пакетът. IP протоколът бил подопълнен, за да се избегнат някои лоши възможности – и пътят към неограниченото развитие на мрежите бил открит.

Та, това е, накратко и много общо, TCP/IP протоколът. 🙂

5 thoughts on “TCP/IP – лекция за начинаещи

  1. Васил Колев

    Сигурно ще ме гледате много на кръв, ама ще се заям …

    1) TCP не е синхронен, не изчаква потвърждението, преди да изпрати пак. Пример за такъв синхронен протокол е TFTP, който е реализиран в/у UDP…
    2) Връзката, че от pipe-овете е тръгнала идеята за мрежата, не ми се вижда много точна… Ако се опира до история, по-скоро трябва да се погледне UUCP и нещата около него като предшественици на пакетните мрежи, и изобщо за смисъла на пакетните мрежи…

    И да си призная, на мен ми е ужасно трудно да го чета, сигурно се дължи на професионалните ми деформации :)))

    Reply
  2. Григор Post author

    Васил: Абсолютно си прав, че много неща тук не са съвсем точно каквито са на практика. 🙂 Идеята обаче е не точна документалност, а някакво пропедевтично обяснение как принципно би трябвало да са нещата. Тук пък сигурно са оставили отпечатък моите професионални деформации… 🙂

    Пейо: Ето че има полза от лекциятаааа! 🙂

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *