„Informatika 2 - Socket kezelés labor” változatai közötti eltérés

A VIK Wikiből
Ugrás a navigációhoz Ugrás a kereséshez
a (David14 átnevezte a(z) Informatika 2 - TCP szerver készítése labor lapot a következő névre: Informatika 2 - Socket kezelés labor: 2013 aktualizálás)
a
 
(22 közbenső módosítás, amit 2 másik szerkesztő végzett, nincs mutatva)
1. sor: 1. sor:
Ez az oldal az [[Informatika 2]] című tárgy - TCP szerver készítése labor beugrókérdéseinek kidolgozását tartalmazza.
+
{{Vissza|Informatika 2}}
 +
 
 +
Ez az oldal az [[Informatika 2]] című tárgy - '''Socket kezelés labor''' beugrókérdéseinek kidolgozását tartalmazza.<br>Az aktuális segédlet az aktuális (ajánlott) beugrókérdésekkel bejelentkezés után megtalálható a tanszéki honlapon a [https://www.aut.bme.hu/Upload/Course/VIAUA203/hallgatoi_segedletek/TCP-HTTP-hallgatoi.pdf 1. gyakorlat segédlet címen] (2013 tavasz).
  
 
Jelenleg még elég hiányos a kidolgozás, továbbá évről évre kismértékben változhatnak beugrókérdések. A tanszéki honlapról mindig elérhető az aktuális mérési útmutató, mely az aktuális beugrókérdéseket tartalmazza.
 
Jelenleg még elég hiányos a kidolgozás, továbbá évről évre kismértékben változhatnak beugrókérdések. A tanszéki honlapról mindig elérhető az aktuális mérési útmutató, mely az aktuális beugrókérdéseket tartalmazza.
 +
 +
'''''FONTOS: Ezektől eltérő kérdések is előfordulhatnak a beugrókban! Ezek csak irányadó kérdések, így ajánlott a segédlet alapos áttanulmányozása is.'''''
  
 
'''Kérlek szerkesszétek, aktualizáljátok!'''
 
'''Kérlek szerkesszétek, aktualizáljátok!'''
 
__TOC__
 
  
 
== Mi a különbség a szerver és a kliens socket között? ==
 
== Mi a különbség a szerver és a kliens socket között? ==
  
 
Szerver:
 
Szerver:
*Bizonyos címen várja az igényeket, majd befutásuk után felépíti a kapcsolatot
+
* Bizonyos címen '''várja''' az igényeket, majd befutásuk után felépíti a kapcsolatot
*Kommunikációra NEM alkalmas, csak kapcsolatok fogadására
+
* Csak passzív módon kommunikál, kliens által létrehozott kapcsolaton keresztül
 +
 
 
Kliens:
 
Kliens:
*A szerver címére kapcsolódási kérést küld, amelyre az reagálhat
+
* A szerver címére kapcsolódási kérést '''küld''', amelyre az reagálhat
*Kommunikációra használjuk
+
* Aktív módon kezdeményezi a kommunikációt
  
 
== A cím összeállításánál miért szükséges a számokat konvertálni? ==
 
== A cím összeállításánál miért szükséges a számokat konvertálni? ==
  
*Több byte-os adattípusokat használunk, de különböző architektúra <math>\rightarrow</math> különböző adatábrázolás (x86=little endian=kisebb helyiértékű byte-al kezd, Sun=big endian)
+
Több bájtos adatstruktúrák írják le a címek különböző részeit (címrész, portszám), és ezek ábrázolása lehet ''big endian'' vagy ''little endian'' bájtsorrendű, amikor a magasabb illetve az alacsonyabb helyiértékű bájtok vannak előbb. (Pl.: az x86 architektúra little endian, a SUN Sparc pedig big endian) A hálózati bájtsorrend mindig valamilyen megegyezés szerint szabványos, minden címnek abban a formátumban kell lennie.
*DE: ezeknek meg kell érteni egymást <math>\rightarrow</math> közös ábrázolás, hálózati byte-sorrend (big endian)
+
 
*Adott architektúrán használt ábrázolás: ''hoszt byte-sorrend''
+
Hogy ne kelljen külön kódot írni attól függően, hogy a gépünk éppen milyen architektúrájú, ezért használjuk a koncerziós függvényeket, amik minden számot a gép ("hoszt") bájtsorrendjéről a hálózat bájtsorrendjére alakítanak.
 +
 
 +
== Milyen függvényekkel tud kommunikálni a kliens és a szerver? ==
  
== Miért szükséges a szerver socketet címhez kötni és miért nem kell a kliens socketet? ==
+
Közvetlenül az <code>int send(SOCKET, const void *, size_t, int)</code> és az <code>int recv(SOCKET, void *, size_t, int)</code> függvényekkel tudnak egymásnak adatokat küldeni, de előtte további függvények segítségével kell a socketeket a kapcsolat felépítéséhez inicializálni.
  
*Szerver: a kliensnek tudni kell, hogy kitől kérjen kiszolgálást <math>\rightarrow</math> '''connect( )-ben KELL''' a cím
+
== A kommunikációs kapcsolatot hogyan zárhatja le a kliens, illetve a szerver oldal? ==
*Kliens: nem feltétlen érdekel a cím <math>\rightarrow</math> '''az accept( )-ben''' a klienscím paramétere '''lehet NULL'''
 
  
== Az accept() függvény meghívásakor mi történik, ha éppen nincs bejövő kapcsolat? ==
+
Az <code>int closesocket(SOCKET)</code> (vagy linux alatt az <code>int close(SOCKET)</code>) függvény meghívásával.
  
Blokkolja a hívó szálat, amíg nem érkezik kapcsolódási kérés. Persze ezt a blokkolást ki lehet kapcsolni, de defaultból blokkol.
+
== Írjon egy „hello világ” programot! ==
  
== A kommunikációs kapcsolatot hogyan zárhatja le a kliens, illetve a szerver oldal? ==
+
#include <stdio.h>
 +
int main(int argc, char** argv) {
 +
    printf("Hello World!\n");
 +
    return 0;
 +
}
  
*''int closesocket(SOCKET s)'' rendszerhívás
+
== C-kód: Lementi egy állományba a „hello” szöveget! ==
*Linux alatt: ''int close(int s)''
 
  
== C-kód: Az s leíróval reprezentált kliens socketből képes 16 byte adat fogadására! ==
+
#include <stdio.h>
 +
int main(int argc, char** argv) {
 +
    // INNENTŐL KELL
 +
    FILE* fp;
 +
    fp = fopen("fajl.txt", "w");
 +
    if (!fp) {
 +
        perror("fopen()-ben hiba volt")
 +
        return -1;
 +
    }
 +
    fprintf(fp, "hello\r\n");
 +
    fclose(fp);
 +
    // IDÁIG KELL
 +
    return 0;
 +
}
  
<pre>
+
== C-kód: Az s leíróval reprezentált kliens kliens socket-en keresztül elküldi a „hello” szöveget! ==
int x;
 
char *buffer;
 
buffer=(char *)malloc(sizeof(char)*16);  /* 16 byte hely lefoglalása */
 
  
x=recv(s, (void *)buffer, sizeof(buffer), 0);
+
int x;
if (x<0) printf("olvasási hiba\n");
+
char message[] = "hello";
if (x==0) printf("olvasás sikeres, a kapcsolat lezárult\n");
+
SOCKET s;
if (x>0) printf("olvasás sikeres\n");
+
// ... itt történne a socket inicializálása
+
// INNENTŐL A LÉNYEG:
free(buffer);
+
x = send(s, (const void *)message, sizeof(message), 0);
</pre>
+
if (x<0) {
 +
    perror("hiba a send() fv-ben");
 +
    return -1;
 +
}
 +
else {
 +
    printf("%d byte elküldve\n", x);
 +
}
  
== C-kód: Az s leíróval reprezentált kliens socketen keresztül elküldi a „hello” stringet! ==
+
== C-kód: Az s leíróval reprezentált kliens socketből képes 64 byte adat fogadására! ==
  
<pre>
+
int x;
int x;
+
char buffer[64];
char message[]="hello";
+
// ... előtte történik a socket inicailizálása
 +
// A LÉNYEG:
 +
x = recv(s, (void *)buffer, sizeof(buffer), 0);
 +
if (x<0) printf("olvasási hiba\n");
 +
if (x>0) printf("olvasás sikeres\n");
 +
if (x==0) printf("olvasás sikeres, a kapcsolat lezárult\n");
  
x=send(s, (const void *)message, sizeof(message), 0);
+
== C-kód: Megvizsgálja, hogy az str1 és str2 nevű karaktertömbök tartalma megegyezik-e! ==
if (x<0) printf("írási hiba\n");
 
else printf("%d byte elküldve\n", x);
 
</pre>
 
  
== C-kód: Megvizsgálja, hogy az str1 és str2 nevű karakter tömbök tartalma megegyezik-e! ==
+
<code>[http://www.cplusplus.com/reference/cstring/strcmp/ int strcmp(const char*, const char*)]</code> függvény dokumentációja
 
<pre>
 
int x;
 
char str1[]="qwerty";
 
char str2[]="spqr";
 
  
x=strcmp(str1, str2);
+
int x;
if (x==0) printf("a két string azonos\n");
+
char str1[]="qwerty";
else printf("a két string különbözı\n");
+
char str2[]="spqr";
</pre>
+
 +
x=strcmp(str1, str2);
 +
if (x==0) printf("a két string azonos\n");
 +
else printf("a két string különböző\n");
  
 
== C-kód: Megvizsgálja, hogy az str1 nevű karakter tömb tartalmazza-e az str2 nevű karakter tömb értékét! ==
 
== C-kód: Megvizsgálja, hogy az str1 nevű karakter tömb tartalmazza-e az str2 nevű karakter tömb értékét! ==
  
<pre>
+
<code>[http://www.cplusplus.com/reference/cstring/strstr/ char* strstr(char*, const char*)]</code> függvény dokumentációja
char str1[]="qwerty";
+
 
char str2[]="spqr";
+
char str1[]="qwerty";
char *temp;
+
char str2[]="spqr";
 +
char *temp;
 +
 +
temp=strstr(str1, str2);
 +
if (temp!=NULL) printf("az első string tartalmazza a másodikat\n");
 +
else printf("az első string nem tartalmazza a másodikat\n");
 +
 
 +
== Egy HTTP kommunikációban milyen felek vesznek részt és mi a feladatuk? ==
 +
 
 +
#Kliens (böngésző):
 +
#*A beírt internetcím alapján megállapítja a szerver IP-címét (lekérdezi egy [http://hu.wikipedia.org/wiki/Domain_Name_System DNS-szervertől (link: Wikipédia)] egy külön kapcsolaton keresztül)
 +
#*TCP/IP-kapcsolatot hoz létre a szerver felé
 +
#*HTTP-kéréseket küld a szerver felé
 +
#Szerver:
 +
#*Nyilvánosan elérhető socketeken keresztül várja a kliensek kapcsolódási kérelmeit
 +
#*HTTP-válaszokat küld a kliens kéréseire (normális esetben például a kért oldalt szolgálja ki, egyéb esetben hibaüzenettel válaszol)
 +
#*Kliensek kéréseire egyéb módon is reagálhat a szerveren (előre meghatározott programot lefuttathat, adatbázist módosíthat, stb.)
 +
#*A válasz végén lebonthatja a kapcsolatot
 +
 
 +
== A HTTP protokollban a kliens hogyan jelzi a kérés fejlécének végét? ==
 +
 
 +
Egy <code><CR><LF><CR><LF></code> sorozattal (<code>0x0D 0x0A 0x0D 0x0A</code> bájtok). Ez magyarul két sortörést (entert) jelent (egy sortörés egy CR-LF). Ha úgy tetszik, akkor egy üres fejléc beszúrásával (mintha a két sortörés között lenne egy üres fejléc).
 +
 
 +
== A HTTP GET kérés hogyan közli a lekérendő dokumentum nevét és elérhetőségét? ==
 +
 
 +
A küldött parancs (pl. <code>GET</code>) után egy szóközzel elválasztva következik a dokumentum helye a szerver gyökérkönyvtárához képest. Pl. a www.google.com szervernek küldött <code>GET / HTTP/1.0</code> kérés magát a gyökérkönyvtárat kéri le (ezt jelöli a perjel).
  
temp=strstr(str1, str2);
+
== A web szerver hogyan jelzi, ha hiba történt a dokumentum lekérése során? ==
if (temp!=NULL) printf("az elsı string tartalmazza a másodikat\n");
 
else printf("az elsı string nem tartalmazza a másodikat\n");
 
</pre>
 
  
== C-kód: Megvizsgálja, hogy az str1 nevű karakter tömb tartalmazza-e a ch nevű karaktert! ==
+
A válasz tartalmaz egy státuszkódot (hibakódot). A 200-as státuszkódok a megfelelő választ jelentik (pl. 200 OK), a 300-asok az átirányítást (pl. 302 Found), a 400-asok a kliens-oldali hibából adódóan nem teljesíthető kérést (pl. 404 Not Found, 403 Forbidden), az 500-asok a szerver-oldali hibából adódóan nem teljesíthető kérést (pl. 500 Internal Server Error)
  
<pre>
+
A (HTTP 1.1-es) válaszkódok bővebben megtalálhatóak a http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html oldalon vagy a Wikipédián: http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
char str1[]="qwerty";
 
char ch='z';
 
char *temp;
 
  
temp=strchr(str1, ch);
+
== Mi az a két mód, ahogy a web szerver jelezheti a dokumentum méretét (végét)? ==
if (temp!=NULL) printf("az elsı string tartalmazza a karaktert\n");
 
else printf("az elsı string nem tartalmazza a karaktert\n");
 
</pre>
 
  
 +
A fejlécben előre elküldheti a dokumentum méretét (pl. Content-Length fejléc mező), vagy az átvitel befejezése után simán bontja a TCP/IP-kapcsolatot.
  
[[Category:Villanyalap]]
+
[[Kategória:Villamosmérnök]]

A lap jelenlegi, 2014. március 13., 16:21-kori változata

← Vissza az előző oldalra – Informatika 2

Ez az oldal az Informatika 2 című tárgy - Socket kezelés labor beugrókérdéseinek kidolgozását tartalmazza.
Az aktuális segédlet az aktuális (ajánlott) beugrókérdésekkel bejelentkezés után megtalálható a tanszéki honlapon a 1. gyakorlat segédlet címen (2013 tavasz).

Jelenleg még elég hiányos a kidolgozás, továbbá évről évre kismértékben változhatnak beugrókérdések. A tanszéki honlapról mindig elérhető az aktuális mérési útmutató, mely az aktuális beugrókérdéseket tartalmazza.

FONTOS: Ezektől eltérő kérdések is előfordulhatnak a beugrókban! Ezek csak irányadó kérdések, így ajánlott a segédlet alapos áttanulmányozása is.

Kérlek szerkesszétek, aktualizáljátok!

Mi a különbség a szerver és a kliens socket között?

Szerver:

  • Bizonyos címen várja az igényeket, majd befutásuk után felépíti a kapcsolatot
  • Csak passzív módon kommunikál, kliens által létrehozott kapcsolaton keresztül

Kliens:

  • A szerver címére kapcsolódási kérést küld, amelyre az reagálhat
  • Aktív módon kezdeményezi a kommunikációt

A cím összeállításánál miért szükséges a számokat konvertálni?

Több bájtos adatstruktúrák írják le a címek különböző részeit (címrész, portszám), és ezek ábrázolása lehet big endian vagy little endian bájtsorrendű, amikor a magasabb illetve az alacsonyabb helyiértékű bájtok vannak előbb. (Pl.: az x86 architektúra little endian, a SUN Sparc pedig big endian) A hálózati bájtsorrend mindig valamilyen megegyezés szerint szabványos, minden címnek abban a formátumban kell lennie.

Hogy ne kelljen külön kódot írni attól függően, hogy a gépünk éppen milyen architektúrájú, ezért használjuk a koncerziós függvényeket, amik minden számot a gép ("hoszt") bájtsorrendjéről a hálózat bájtsorrendjére alakítanak.

Milyen függvényekkel tud kommunikálni a kliens és a szerver?

Közvetlenül az int send(SOCKET, const void *, size_t, int) és az int recv(SOCKET, void *, size_t, int) függvényekkel tudnak egymásnak adatokat küldeni, de előtte további függvények segítségével kell a socketeket a kapcsolat felépítéséhez inicializálni.

A kommunikációs kapcsolatot hogyan zárhatja le a kliens, illetve a szerver oldal?

Az int closesocket(SOCKET) (vagy linux alatt az int close(SOCKET)) függvény meghívásával.

Írjon egy „hello világ” programot!

#include <stdio.h>
int main(int argc, char** argv) {
    printf("Hello World!\n");
    return 0;
}

C-kód: Lementi egy állományba a „hello” szöveget!

#include <stdio.h>
int main(int argc, char** argv) {
    // INNENTŐL KELL
    FILE* fp;
    fp = fopen("fajl.txt", "w");
    if (!fp) {
        perror("fopen()-ben hiba volt")
        return -1;
    }
    fprintf(fp, "hello\r\n");
    fclose(fp);
    // IDÁIG KELL
    return 0;
}

C-kód: Az s leíróval reprezentált kliens kliens socket-en keresztül elküldi a „hello” szöveget!

int x;
char message[] = "hello";
SOCKET s;
// ... itt történne a socket inicializálása
// INNENTŐL A LÉNYEG:
x = send(s, (const void *)message, sizeof(message), 0);
if (x<0) {
    perror("hiba a send() fv-ben");
    return -1;
}
else {
    printf("%d byte elküldve\n", x);
}

C-kód: Az s leíróval reprezentált kliens socketből képes 64 byte adat fogadására!

int x;
char buffer[64];
// ... előtte történik a socket inicailizálása
// A LÉNYEG:
x = recv(s, (void *)buffer, sizeof(buffer), 0);
if (x<0) printf("olvasási hiba\n");
if (x>0) printf("olvasás sikeres\n");
if (x==0) printf("olvasás sikeres, a kapcsolat lezárult\n");

C-kód: Megvizsgálja, hogy az str1 és str2 nevű karaktertömbök tartalma megegyezik-e!

int strcmp(const char*, const char*) függvény dokumentációja

int x;
char str1[]="qwerty";
char str2[]="spqr";

x=strcmp(str1, str2);
if (x==0) printf("a két string azonos\n");
else printf("a két string különböző\n");

C-kód: Megvizsgálja, hogy az str1 nevű karakter tömb tartalmazza-e az str2 nevű karakter tömb értékét!

char* strstr(char*, const char*) függvény dokumentációja

char str1[]="qwerty";
char str2[]="spqr";
char *temp;

temp=strstr(str1, str2);
if (temp!=NULL) printf("az első string tartalmazza a másodikat\n");
else printf("az első string nem tartalmazza a másodikat\n");

Egy HTTP kommunikációban milyen felek vesznek részt és mi a feladatuk?

  1. Kliens (böngésző):
    • A beírt internetcím alapján megállapítja a szerver IP-címét (lekérdezi egy DNS-szervertől (link: Wikipédia) egy külön kapcsolaton keresztül)
    • TCP/IP-kapcsolatot hoz létre a szerver felé
    • HTTP-kéréseket küld a szerver felé
  2. Szerver:
    • Nyilvánosan elérhető socketeken keresztül várja a kliensek kapcsolódási kérelmeit
    • HTTP-válaszokat küld a kliens kéréseire (normális esetben például a kért oldalt szolgálja ki, egyéb esetben hibaüzenettel válaszol)
    • Kliensek kéréseire egyéb módon is reagálhat a szerveren (előre meghatározott programot lefuttathat, adatbázist módosíthat, stb.)
    • A válasz végén lebonthatja a kapcsolatot

A HTTP protokollban a kliens hogyan jelzi a kérés fejlécének végét?

Egy <CR><LF><CR><LF> sorozattal (0x0D 0x0A 0x0D 0x0A bájtok). Ez magyarul két sortörést (entert) jelent (egy sortörés egy CR-LF). Ha úgy tetszik, akkor egy üres fejléc beszúrásával (mintha a két sortörés között lenne egy üres fejléc).

A HTTP GET kérés hogyan közli a lekérendő dokumentum nevét és elérhetőségét?

A küldött parancs (pl. GET) után egy szóközzel elválasztva következik a dokumentum helye a szerver gyökérkönyvtárához képest. Pl. a www.google.com szervernek küldött GET / HTTP/1.0 kérés magát a gyökérkönyvtárat kéri le (ezt jelöli a perjel).

A web szerver hogyan jelzi, ha hiba történt a dokumentum lekérése során?

A válasz tartalmaz egy státuszkódot (hibakódot). A 200-as státuszkódok a megfelelő választ jelentik (pl. 200 OK), a 300-asok az átirányítást (pl. 302 Found), a 400-asok a kliens-oldali hibából adódóan nem teljesíthető kérést (pl. 404 Not Found, 403 Forbidden), az 500-asok a szerver-oldali hibából adódóan nem teljesíthető kérést (pl. 500 Internal Server Error)

A (HTTP 1.1-es) válaszkódok bővebben megtalálhatóak a http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html oldalon vagy a Wikipédián: http://en.wikipedia.org/wiki/List_of_HTTP_status_codes

Mi az a két mód, ahogy a web szerver jelezheti a dokumentum méretét (végét)?

A fejlécben előre elküldheti a dokumentum méretét (pl. Content-Length fejléc mező), vagy az átvitel befejezése után simán bontja a TCP/IP-kapcsolatot.