Crearea unui joc cu Bonjour - Prezentare generală a rețelei

Bonjour este o tehnologie care face descoperirea de servicii foarte ușoară. În ciuda puterii și a ușurinței de utilizare, nu primește prea multă atenție în comunitatea de cacao. Bonjour funcționează foarte bine cu biblioteca CocoaAsyncSocket, o bibliotecă open-source care oferă o interfață Obiectiv-C pentru lucrul cu mufe de pe iOS și OS X. În această serie, vă prezint Bonjour și biblioteca CocoaAsyncSocket creând un simplu, joc în rețea. Pe parcurs, vă voi iniția în lumea rețelelor, discutând protocoalele TCP și UDP, precum și prizele, fluxurile și porturile!


Introducere

În această serie, vom crea un joc simplu în rețea. Accentul nostru principal va fi aspectul de rețea al jocului. Vă voi arăta cum să conectați două dispozitive folosind Bonjour și biblioteca puternică CocoaAsyncSocket. Jocul pe care îl vom crea permite celor doi oameni din aceeași rețea să se conteste reciproc. Jocul în sine nu va fi foarte avansat, așa că nu vă așteptați la un FPS grafic bogat.

În această serie, nu voi vorbi despre infrastructura care permite aplicațiilor în rețea să comunice una cu cealaltă. În schimb, mă voi concentra pe protocoalele și tehnologiile care formează fundamentul aplicațiilor în rețea. O înțelegere de bază a protocoalelor, soclurilor și fluxurilor TCP și UDP este de neprețuit pentru orice dezvoltator, în special pentru cei care intenționează să creeze aplicații care se bazează pe conectivitate în rețea. Chiar dacă nu intenționați să utilizați Bonjour, vă recomand să citiți restul acestui articol pentru a obține o mai bună înțelegere a rețelei.

În acest articol, voi mări câteva componente cheie ale aplicațiilor în rețea. Vă va ajuta să înțelegeți cum funcționează Bonjour, ce este Bonjour (și nu este) și că va face mult mai ușor lucrul cu biblioteca CocoaAsyncSocket.

Rețineți că Bonjour nu are obligația de a dezvolta o aplicație în rețea. Cele mai multe sisteme de operare bazate pe Unix, cum ar fi iOS și OS X, folosesc prize BSD ca interfață fundamentală de programare a rețelei. Pe iOS și OS X, biblioteca BSD Socket este disponibilă imediat. Lucrul cu biblioteca BSD Socket însă nu este pentru cei slabi de inimă și necesită o cunoaștere aprofundată a programării socket-urilor și a limbajului C. Pe iOS și OS X, puteți utiliza și un nivel redus CFNetwork cadru, care este o extensie directă la prizele BSD. Apple a proiectat cadrul CFNetwork pentru a facilita crearea de rețele prin evitarea interacțiunii directe cu soclurile BSD. Unul dintre cele mai importante avantaje ale rețelei CFN este suportul integrat pentru integrarea în buclă. Rețeaua CFN face parte din cadrul Fundației Core și este scrisă în C.

Un număr surprinzător de dezvoltatori iOS și OS X sunt atât de obișnuiți cu sintaxa Objective-C pe care ei o îndepărtează de bibliotecile și cadrele scrise în C. Dacă sunteți unul dintre acei dezvoltatori, atunci cadrul CFNetwork poate părea descurajant. Cu toate acestea, există o soluție pentru acest lucru, iar numele său este CocoaAsyncSocket. Biblioteca CocoaAsyncSocket face mai ușoară interacțiunea cu prizele și oferă, de asemenea, o interfață elegantă C-C. Versiunea curentă a bibliotecii CocoaAsyncSocket se integrează perfect cu Grand Central Dispatch (GCD), care face programarea asincronă o briză.


Să începem să aruncăm o privire mai atentă la elementele de bază ale rețelei. Fără o bună înțelegere a prizelor, a porturilor și a fluxurilor, chiar Bonjour și biblioteca CocoaAsyncSocket nu vă vor fi de mare folos!


Învățarea rețelelor

Sub capotă

Lucrul în rețea nu este ușor și acest lucru nu se va schimba în curând. Chiar dacă infrastructura care ne oferă acces la Internet sa schimbat dramatic în ultimele decenii, tehnologiile și protocoalele de bază s-au schimbat foarte puțin. Motivul este că serviciile pe care le folosim zilnic se bazează foarte mult pe protocoalele logice de bază și mult mai puțin pe infrastructura fizică. În anii nouăzeci, cei mai mulți dintre noi am navigat pe web printr-o conexiune dial-up. În prezent, majoritatea oamenilor au acces la o conexiune rapidă în bandă largă, iar în ultimii ani o parte semnificativă a rețelei a început să fie consumată prin intermediul dispozitivelor mobile. Cu alte cuvinte, infrastructura sa schimbat dramatic, însă protocoalele logice necesare pentru rutarea traficului și interacțiunea cu aplicațiile nu s-au schimbat dramatic.

Niciodată nu schimbați o echipă câștigătoare

Un alt motiv pentru care tehnologiile și protocoalele fundamentale pe care le folosim pentru a transmite date pe Internet nu s-au schimbat prea mult se datorează faptului că s-au dovedit a fi fiabile, performante și robuste. Aceste tehnologii și protocoale sunt bine testate și s-au dovedit de nenumărate ori în ultimele decenii.


Sockets, Streams și Ports

Ca dezvoltator, probabil ați auzit despre prize, porturi, adrese și altele asemenea. Dacă nu sunteți familiarizați cu acești termeni, atunci vă aflați într-un tratament, deoarece vă voi prezenta minunile prizelor, porturilor, fluxurilor și protocoalelor. Pentru a obține o înțelegere de bază a rețelei, este cheia pe care o cunoașteți bazele rețelei și care include prizele și prietenii.

Socket-uri locale și de la distanță

O conexiune de rețea funcționează prin prize. Un soclu este un capăt al unui canal de comunicare între două procese care vor să discute între ele. După cum probabil ați ghicit, o conexiune la rețea (sau un canal de comunicare interproces) are două prize, câte unul pentru fiecare capăt al canalului. O conexiune la rețea este stabilită de un singur soclu care realizează o conexiune cu un alt soclu, soclul de ascultare, care ascultă conexiunile de intrare.

Diferența dintre o priză locală și cea de la distanță este pur și simplu semantică. Din perspectiva unui soclu, priza este soclul local și soclul la care este conectat este soclul la distanță. Are sens. Dreapta?

În timp ce un socket este utilizat pentru a trimite și primi date, un flux poate citi date sau scrie date. Aceasta înseamnă că, în majoritatea cazurilor, fiecare soclu are două fluxuri, unul pentru citire și unul pentru scriere. Chiar dacă fluxurile reprezintă un aspect important al programării socket-urilor, nu vom lucra cu fluxurile direct, deoarece fluxurile sunt gestionate pentru noi de către biblioteca CocoaAsyncSocket.

Stabilirea unei conexiuni de rețea

Fiecare soclu are un adresa care constă din adresa gazdă și a numarul portului. Ambele părți sunt esențiale pentru a stabili o conexiune între două prize. Pentru a menține lucrurile simple, adresa gazdă este de obicei adresa IP (Internet Protocol) a aparatului, în timp ce numărul portului identifică în mod unificat soclul de pe aparat. Comparați acest concept cu un complex de apartamente. Clădirea are o adresă, astfel încât oamenii să știe unde să o găsească. Fiecare apartament în clădire are un număr unic, astfel vizitatorii complexului pot găsi apartamentul pe care îl caută.

Protocoale de transmisie

Transmiterea datelor pe Internet este un proces complex și a dus la crearea a două protocoale robuste pentru trimiterea și primirea uniformă a datelor: TCP (Transmission Control Protocol) și UDP (User Datagram Protocol). Ambele protocoale sunt protocoalele stratului de transport și o parte din Protocolul de Internet (IP).

Sunt sigur că TCP și UDP sună cu majoritatea dintre voi. Există mai multe diferențe cheie între cele două protocoale și este important să înțelegem aceste diferențe. În această serie, ne vom concentra pe protocolul TCP. O conexiune TCP gestionează un flux de date de la un punct final la altul.

Fiabilitatea rețelei

Principalele diferențe dintre TCP și UDP sunt viteză și cum se descurcă siguranța rețelei. Dacă doriți să vă asigurați că ceea ce este trimis printr-un capăt al conexiunii iese la celălalt capăt, atunci TCP este prietenul tău. TCP este mai lent decât UDP, dar are un motiv bun pentru a fi mai lent. Fără a intra în prea multe detalii, este important să știm că TCP stabilește și termină o conexiune cu o strângere de mână pentru a identifica ambele capete ale conexiunii. Se asigură, de asemenea, că fiecare pachet trimis prin canal ajunge la celălalt capăt. În plus, TCP asigură respectarea ordinii pachetelor.

Unul dintre motivele pentru care UDP este mai rapid decât TCP este că nu necesită o strângere de mână la stabilirea și terminarea unei conexiuni. În plus, protocolul UDP nu are grijă dacă sosește un pachet și nu îi pasă de ordinea în care sosesc pachetele. Dacă un pachet este abandonat de-a lungul drumului, protocolul UDP nu încearcă să îl retransmită, deoarece nici măcar nu este conștient de abandonul pachetului. Principala preocupare a UDP este că datele sunt trimise pe canalul de comunicare cât mai repede posibil.

Sunt sigur că începi să vezi că TCP și UDP sunt protocoale foarte diferite și că fiecare protocol are un scop diferit. UDP, de exemplu, este ideal pentru streaming audio și video live. Viteza este esențială în aceste situații. Nu contează dacă un pachet este abandonat de-a lungul drumului. Dacă un pachet abandonat va fi respins, ar ajunge târziu și pentru streaming live nu va mai fi relevant. Jocuri multiplayer online beneficiază, de asemenea, de UDP. Viteza UDP este mai importantă decât fiabilitatea acesteia. Pachetele care ajung prea târziu nu mai sunt relevante și aceasta este ideea fundamentală din spatele UDP - viteza peste fiabilitate.

TCP, pe de altă parte, este vorba despre fiabilitate. Acesta este folosit pentru e-mail și navigarea pe web. Este un pic mai lent, dar va face tot ce este mai bun pentru a vă asigura că primiți ceea ce ați cerut. Protocolul TCP este foarte robust și acceptă retrimiterea pachetelor abandonate și respectă și ordinea în care sunt trimise pachetele. Chiar dacă vom folosi protocolul TCP din această serie, rețineți că biblioteca CocoaAsyncSocket suportă, de asemenea, protocolul UDP.

Client și Server

În ceea ce privește crearea de rețele, există încă un concept pe care trebuie să îl înțelegeți: modelul client-server. În fiecare comunicare, există un client și un server. Comparați acest model cu cei doi oameni care efectuează un apel telefonic. Steven vrea să facă un telefon la Lucy. Există trei cerințe fundamentale pentru ca acest lucru să funcționeze.

  1. Prima cerință este că Steven știe despre Lucy și trebuie să știe numărul de telefon al lui Lucy. Același lucru este valabil și pentru un client care încearcă să se conecteze la un server. Clientul trebuie să știe despre existența serverului și trebuie să știe adresa serverului.
  2. Opusul, totuși, nu este adevărat. Lucy nu are nevoie să știe nimic despre Steven pentru Steven să o sune pe Lucy. Cu alte cuvinte, un server nu are nevoie să știe despre existența unui client pentru ca clientul să se conecteze la server.
  3. Odată ce conexiunea este stabilită, Steven poate să vorbească cu Lucy, iar Lucy poate vorbi cu Steven. Atunci când un client este conectat la un server, clientul poate trimite date către server și serverul poate trimite date către client.

Acest concept al unui client și al unui server va deveni important atunci când ne uităm la Bonjour în practică în următorul articol din această serie. Să încheiem acest tutorial luând o scurtă privire la Bonjour.


Unde se potrivește Bonjour?

Ce este Bonjour și cum se potrivește în povestea noastră? Bonjour este o tehnologie creată de Apple și bazată pe Zeroconf. Scopul său principal este de a facilita descoperirea serviciilor. Sunt șanse să folosești Bonjour de nenumărate ori fără să știi asta. Ați folosit vreodată o imprimantă în rețeaua locală? Nu v-a greșit că nu a fost nevoie de aproape nici un efort să utilizați imprimanta, chiar dacă nu a fost conectată fizic la computer? Aplicația iOS de la distanță de la Apple folosește de asemenea Bonjour, la fel și alte aplicații iOS și OS X.

Chiar dacă Bonjour este o tehnologie excelentă, rețineți că nu are grijă să trimiteți sau să primiți date. Ceea ce face Bonjour este publicarea și descoperirea serviciilor care se află în aceeași rețea locală. În următorul articol, vom examina mai atent Bonjour's API-uri și vom începe să construim modelul client-server pe care l-am discutat în acest articol.


Concluzie

Cu acest tutorial introductiv ar trebui să aveți o înțelegere de bază a rețelelor, a diverselor componente implicate și a rolului fiecărei componente. În celelalte părți ale acestei serii vom revedea și vom folosi câteva dintre aceste componente, astfel că este esențial să înțelegeți ce am acoperit în acest articol. În următorul articol, voi vorbi mai multe despre modelul client-server arătându-vă cum să conectați două dispozitive folosind Bonjour și biblioteca CocoaAsyncSocket.

Cod