(Допълнена на 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 протоколът. 🙂
Попросветна ми! Благодаря ти!
Сигурно ще ме гледате много на кръв, ама ще се заям …
1) TCP не е синхронен, не изчаква потвърждението, преди да изпрати пак. Пример за такъв синхронен протокол е TFTP, който е реализиран в/у UDP…
2) Връзката, че от pipe-овете е тръгнала идеята за мрежата, не ми се вижда много точна… Ако се опира до история, по-скоро трябва да се погледне UUCP и нещата около него като предшественици на пакетните мрежи, и изобщо за смисъла на пакетните мрежи…
И да си призная, на мен ми е ужасно трудно да го чета, сигурно се дължи на професионалните ми деформации :)))
А аз пък разбрах какво означава муфа в действителност 🙂
Васил: Абсолютно си прав, че много неща тук не са съвсем точно каквито са на практика. 🙂 Идеята обаче е не точна документалност, а някакво пропедевтично обяснение как принципно би трябвало да са нещата. Тук пък сигурно са оставили отпечатък моите професионални деформации… 🙂
Пейо: Ето че има полза от лекциятаааа! 🙂
Много ми хареса! Достъпно и лесно за разбиране!