Differences

This shows you the differences between two versions of the page.

Link to this comparison view

eim:laboratoare:laborator06 [2016/04/08 07:17]
tmp.andrei.cojocaru
eim:laboratoare:laborator06 [2022/04/14 12:48] (current)
dragos.niculescu
Line 1: Line 1:
-====== Laborator 06. Comunicația prin Sockeți ​TCP ====== +====== Laborator 06. Comunicația prin Sockeți ​în Android ​====== 
 + 
 ===== Realizarea Conexiunii între o Mașină Fizică și Dispozitivul Mobil ===== ===== Realizarea Conexiunii între o Mașină Fizică și Dispozitivul Mobil =====
  
 Pentru a putea comunica prin intermediul unui socket TCP, o mașină fizică și dispozitivul mobil trebuie să se găsească în aceeași rețea, astfel încât adresele IP ale acestora să fie vizibile între ele. Pentru a putea comunica prin intermediul unui socket TCP, o mașină fizică și dispozitivul mobil trebuie să se găsească în aceeași rețea, astfel încât adresele IP ale acestora să fie vizibile între ele.
 +=== Comenzi utile ===
 +  *  <code shell>​vbox86p:/​ # ip ro 
 +172.16.4.0/​22 dev eth1  proto kernel ​ scope link  src 172.16.7.89 ​
 +192.168.57.0/​24 dev eth0  proto kernel ​ scope link  src 192.168.57.101 ​
 +</​code> ​ interfețele,​ adresele, rutele (în telefon sau emulator)
 +  * <code shell>​student@eg106:​~$ ip ro
 +default via 172.16.7.254 dev eno1 proto dhcp metric 100 
 +169.254.0.0/​16 dev eno1 scope link metric 1000 
 +172.16.4.0/​22 dev eno1 proto kernel scope link src 172.16.7.36 metric 100 
 +172.16.101.0/​24 dev vmnet1 proto kernel scope link src 172.16.101.1 ​
 +192.168.57.0/​24 dev vboxnet1 proto kernel scope link src 192.168.57.1 ​
 +</​code> ​ interfețele,​ adresele, rutele (mașina de dezvoltare Linux)
 +  * <code shell>​netstat -rn</​code> ​ interfețele,​ adresele, rutele (mașina de dezvoltare OSX)
 +  * <code shell>​ipconfig</​code> ​ interfețele,​ adresele, rutele (în telefon sau emulator)  ​
  
 ==== Dispozitiv Fizic ==== ==== Dispozitiv Fizic ====
Line 14: Line 28:
 Pe telefon, se accesează //​Settings//​ → //Wireless & Networks// → //Tethering & portable hotspot// și se selectează opțiunea //USB  Tethering// Pe telefon, se accesează //​Settings//​ → //Wireless & Networks// → //Tethering & portable hotspot// și se selectează opțiunea //USB  Tethering//
  
 +{{ :​eim:​laboratoare:​laborator06:​usb_tethering_configuration.png?​nolink&​400 }}
  
 Astfel, se va activa (în mod automat) interfața ''​rndis0'',​ pentru care se poate determina adresa Internet: Astfel, se va activa (în mod automat) interfața ''​rndis0'',​ pentru care se poate determina adresa Internet:
  
 <​code>​ <​code>​
-student@eim2016:/​opt/​android-sdk-linux/​platform-tools$ ./adb devices+student@eim-lab:/​opt/​android-sdk-linux/​platform-tools$ ./adb devices
 List of devices attached List of devices attached
 0019531d59461f ​   device 0019531d59461f ​   device
-student@eim2016:/​opt/​android-sdk-linux/​platform-tools$ ./adb -s 0019531d59461f shell+student@eim-lab:/​opt/​android-sdk-linux/​platform-tools$ ./adb -s 0019531d59461f shell
 shell@n7000:/​ $ su shell@n7000:/​ $ su
 su su
Line 33: Line 47:
 <note important>​Pe Linux, în situația în care dispozitivul mobil este detectat, fără a se indica tipul său, este necesar să se pornească serverul de ADB cu drepturi de administrator:​ <note important>​Pe Linux, în situația în care dispozitivul mobil este detectat, fără a se indica tipul său, este necesar să se pornească serverul de ADB cu drepturi de administrator:​
 <​code>​ <​code>​
-student@eim2016:/​opt/​android-sdk-linux/​platform-tools$ ./adb devices+student@eim-lab:/​opt/​android-sdk-linux/​platform-tools$ ./adb devices
 List of devices attached List of devices attached
 0019531d59461f ​   ????????????​ 0019531d59461f ​   ????????????​
-student@eim2016:/​opt/​android-sdk-linux/​platform-tools$ sudo ./adb kill-server +student@eim-lab:/​opt/​android-sdk-linux/​platform-tools$ sudo ./adb kill-server 
-student@eim2016:/​opt/​android-sdk-linux/​platform-tools$ sudo ./adb start-server +student@eim-lab:/​opt/​android-sdk-linux/​platform-tools$ sudo ./adb start-server 
-student@eim2016:/​opt/​android-sdk-linux/​platform-tools$ sudo ./adb devices+student@eim-lab:/​opt/​android-sdk-linux/​platform-tools$ sudo ./adb devices
 List of devices attached List of devices attached
 0019531d59461f ​   device 0019531d59461f ​   device
 </​code>​ </​code>​
  
-Pentru dispozitivele care nu permit conectarea cu ''​adb shell'' ​in modul tethering [[http://​stackoverflow.com/​questions/​9210152/​set-up-device-for-development-no-permissions|soluție stackoverflow]]trebuie creat în Ubuntu fișierul ''/​etc/​udev/​rules.d/​51-android.rules''​ și adăugat codul obținut cu ''​lsusb''​ pentru fabricantul telefonului. Odată dispozitivul de rețea obținut (de exemplu ''​rndis0''​),​ se folosește ''​dhclient rndis0''​ pentru a obține o adresă IP de la telefon.  ​+Pentru dispozitivele care nu permit conectarea cu ''​adb shell'' ​în modul tethering ​se aplică ​[[http://​stackoverflow.com/​questions/​9210152/​set-up-device-for-development-no-permissions|soluția prezentată pe stackoverflow]]trebuie creat în Ubuntu fișierul ''/​etc/​udev/​rules.d/​51-android.rules''​ și adăugat codul obținut cu ''​lsusb''​ pentru fabricantul telefonului. Odată dispozitivul de rețea obținut (de exemplu ''​rndis0''​),​ se folosește ''​dhclient rndis0''​ pentru a obține o adresă IP de la telefon.  ​
  
 Pe Windows, dacă dispozitivul mobil nu este detectat, poate fi necesară instalarea unor drivere suplimentare pentru stabilirea legăturii prin intermediul portului USB. Pe Windows, dacă dispozitivul mobil nu este detectat, poate fi necesară instalarea unor drivere suplimentare pentru stabilirea legăturii prin intermediul portului USB.
Line 49: Line 63:
  
 Ulterior, se determină adresa Internet a mașinii fizice, asociată interfeței ''​usb0''​ (Linux), respectiv Ethernet (Windows). Ulterior, se determină adresa Internet a mașinii fizice, asociată interfeței ''​usb0''​ (Linux), respectiv Ethernet (Windows).
- 
-<columns 100% 50%> 
  
 **Linux** **Linux**
  
 <​code>​ <​code>​
-student@eim2016:~$ sudo ifconfig usb0+student@eim-lab:~$ sudo ifconfig usb0
 usb0      Link encap:​Ethernet ​ HWaddr 32:​ca:​4b:​1c:​ff:​7b ​ usb0      Link encap:​Ethernet ​ HWaddr 32:​ca:​4b:​1c:​ff:​7b ​
           inet addr:​192.168.42.170 ​ Bcast:​192.168.42.255 ​ Mask:​255.255.255.0           inet addr:​192.168.42.170 ​ Bcast:​192.168.42.255 ​ Mask:​255.255.255.0
Line 65: Line 77:
           RX bytes:24103 (23.5 KiB)  TX bytes:64369 (62.8 KiB)           RX bytes:24103 (23.5 KiB)  TX bytes:64369 (62.8 KiB)
 </​code>​ </​code>​
- 
-<​newcolumn>​ 
  
 **Windows** **Windows**
Line 84: Line 94:
    ​Default Gateway . . . . . . . . . : 192.168.42.129    ​Default Gateway . . . . . . . . . : 192.168.42.129
 </​code>​ </​code>​
- 
-</​columns>​ 
  
 ==== Dispozitiv Virtual (Emulator) ==== ==== Dispozitiv Virtual (Emulator) ====
Line 92: Line 100:
  
 Fiecărui dispozitiv virtual Genymotion îi este alocată în mod automat o adresă IP de către serverul DHCP configurat pe mașina virtuală VirtualBox în cadrul căruia rulează. ​ Fiecărui dispozitiv virtual Genymotion îi este alocată în mod automat o adresă IP de către serverul DHCP configurat pe mașina virtuală VirtualBox în cadrul căruia rulează. ​
- +Pentru legătura virtualbox-emulator ​este utilizat spațiul de adrese ''​192.168.56.1/​24'':​
-Implicit, ​este utilizat spațiul de adrese ''​192.168.56.1/​24'':​+
   * mașina fizică (default gateway) are adresa ''​192.168.56.1'';​   * mașina fizică (default gateway) are adresa ''​192.168.56.1'';​
   * pentru dispozitivele virtuale sunt alocate adrese în intervalul ''​192.168.56.101''​ .. ''​192.168.56.254''​.   * pentru dispozitivele virtuale sunt alocate adrese în intervalul ''​192.168.56.101''​ .. ''​192.168.56.254''​.
 +Pentru legătura wifi a emulatorului utilizat spațiul de adrese ''​172.16.4.0/​22'':​
 +  * de fapt emulatorul este legat în bridge cu celelalte desktopuri din EG106
 +  * conectarea între masina de dezvoltare și emulator se poate face și în această subrețea (similară cu cazul real în care mașina de dezvoltare și telefonul se află în aceeași rețea locală WiFi)
  
 Configurarea spațiului de adrese care este folosit poate fi configurat prin intermediul VirtualBox, accesând //File// → //​Preferences//​ → //Network// → //Host Only Networks// Configurarea spațiului de adrese care este folosit poate fi configurat prin intermediul VirtualBox, accesând //File// → //​Preferences//​ → //Network// → //Host Only Networks//
Line 105: Line 115:
 Adresa IP care a fost atașată fiecărui dispozitiv virtual Genymotion poate fi verificată:​ Adresa IP care a fost atașată fiecărui dispozitiv virtual Genymotion poate fi verificată:​
   * folosind comanda ''​adb devices'';​ <​code>​   * folosind comanda ''​adb devices'';​ <​code>​
-student@eim2016:/​opt/​android-sdk-linux/​platform-tools$ ./adb devices+student@eim-lab:/​opt/​android-sdk-linux/​platform-tools$ ./adb devices
 List of devices attached List of devices attached
 192.168.56.101:​5555 ​    ​device 192.168.56.101:​5555 ​    ​device
Line 113: Line 123:
 {{ :​eim:​laboratoare:​laborator06:​genymotion_ip_addresses.png?​nolink&​700 }} {{ :​eim:​laboratoare:​laborator06:​genymotion_ip_addresses.png?​nolink&​700 }}
  
-Conectivitatea dintre mașina ​fizică ​și dispozitivul virtual poate fi verificată folosind comanda ''​ping''​. <​code>​ +Conectivitatea dintre mașina ​de dezvoltare ​și dispozitivul virtual poate fi verificată folosind comanda ''​ping''​. <​code>​ 
-student@eim2016:~$ ping 192.168.56.101+student@eim-lab:~$ ping 192.168.56.101
 Pinging 192.168.56.101 with 32 bytes of data: Pinging 192.168.56.101 with 32 bytes of data:
 Reply from 192.168.56.101:​ bytes=32 time<1ms TTL=64 Reply from 192.168.56.101:​ bytes=32 time<1ms TTL=64
Line 139: Line 149:
  
   * prin rularea comenzii ''​adb devices''​ <​code>​   * prin rularea comenzii ''​adb devices''​ <​code>​
-student@eim2016:/​opt/​android-sdk-linux/​platform-tools$ ./adb devices+student@eim-lab:/​opt/​android-sdk-linux/​platform-tools$ ./adb devices
 List of devices attached List of devices attached
 emulator-5554 ​  ​device emulator-5554 ​  ​device
Line 145: Line 155:
  
 Conectarea la consola dispozitivului virtual Android se face prin comanda: <​code>​ Conectarea la consola dispozitivului virtual Android se face prin comanda: <​code>​
-student@eim2016:~$ telnet localhost 55nr+student@eim-lab:~$ telnet localhost 55nr
 </​code>​ </​code>​
 specificându-se portul pe care rulează emulatorul. specificându-se portul pe care rulează emulatorul.
  
-În consolă, realizarea unei legături între mașina fizică și dispozitivul virtual Android se face prin [[http://​developer.android.com/​tools/​devices/​emulator.html#​portredirection|redirectarea portului]], folosind comanda ''​redir'',​ aceasta suportând mai multe opțiuni:+<note important>​ 
 +Este necesară și autentificarea pe dispozitivul virtual respectiv, folosind o cheie care a fost instalată odată cu acesta, a cărei locație este indicată. În acest sens, se folosește comanda ''​auth'',​ urmată de cheia dispozitivului virtual. Cheia se află în ~/​.emulator_console_auth_token  
 +</​note>​ 
 + 
 +În consolă, realizarea unei legături între mașina fizică și dispozitivul virtual Android se face prin [[http://​developer.android.com/​tools/​help/​emulator.html#​redirection|redirectarea portului]], folosind comanda ''​redir'',​ aceasta suportând mai multe opțiuni:
   * ''​list'';​   * ''​list'';​
   * ''​add'';​   * ''​add'';​
Line 162: Line 176:
  
 <​code>​ <​code>​
-student@eim2016:~$ telnet localhost 5554+student@eim-lab:~$ telnet localhost 5554
 Android Console: type '​help'​ for a list of commands Android Console: type '​help'​ for a list of commands
 OK OK
Line 177: Line 191:
 exit exit
 Connection to host lost. Connection to host lost.
-student@eim2016:~$+student@eim-lab:~$
 </​code>​ </​code>​
  
Line 220: Line 234:
 <code java> <code java>
 String hostname = "​localhost";​ String hostname = "​localhost";​
-int port = 2016;+int port = 2000;
 Socket socket = new Socket(hostname,​ port); Socket socket = new Socket(hostname,​ port);
 </​code>​ </​code>​
Line 242: Line 256:
  
 Metodele implementate de clasa [[http://​developer.android.com/​reference/​java/​io/​PrintWriter.html|PrintWriter]] sunt similare cu cele oferite de ''​PrintStream''​ (clasa folosită de metodele din ''​System.out''​),​ diferența fiind faptul că pot fi create mai multe instanțe pentru seturi de caractere Unicode diferite: Metodele implementate de clasa [[http://​developer.android.com/​reference/​java/​io/​PrintWriter.html|PrintWriter]] sunt similare cu cele oferite de ''​PrintStream''​ (clasa folosită de metodele din ''​System.out''​),​ diferența fiind faptul că pot fi create mai multe instanțe pentru seturi de caractere Unicode diferite:
-  * ''​print()''​+  * [[https://​developer.android.com/​reference/​java/​io/​PrintWriter.html#​print(java.lang.Object)|print()]]
-  * ''​println()''​+  * [[https://​developer.android.com/​reference/​java/​io/​PrintWriter.html#​println(java.lang.Object)|println()]]
-  * ''​printf()''​+  * [[https://​developer.android.com/​reference/​java/​io/​PrintWriter.html#​printf(java.lang.String,​%20java.lang.Object...)|printf()]]
-  * ''​write()''​.+  * [[https://​developer.android.com/​reference/​java/​io/​PrintWriter.html#​write(char[])|write()]].
  
-Trimiterea efectivă a datelor este realizată atunci când se apelează metoda ​''​flush()''​.+Trimiterea efectivă a datelor este realizată atunci când se apelează metoda ​[[https://​developer.android.com/​reference/​java/​io/​PrintWriter.html#​flush()|flush()]] sau automat la întâlnirea caracterului ​'\n', în funcție de argumentele cu care a fost invocat constructorul.
  
 **3.** crearea unui flux de intrare pentru a primi date prin intermediul socket-ului TCP și primirea efectivă a datelor: **3.** crearea unui flux de intrare pentru a primi date prin intermediul socket-ului TCP și primirea efectivă a datelor:
Line 256: Line 270:
 </​code>​ </​code>​
  
-<note important>​Un obiect de tip ''​BufferedReader''​ poate stoca maxim 8192 de caractere în zona de memorie tampon de care dispune.</​note>​ 
  
 Metodele implementate de clasa [[http://​developer.android.com/​reference/​java/​io/​BufferedReader.html|BufferedReader]] sunt: Metodele implementate de clasa [[http://​developer.android.com/​reference/​java/​io/​BufferedReader.html|BufferedReader]] sunt:
-  * ''​read()'' ​- pentru a primi un singur caracter (dacă este apelată fără parametrii) sau un tablou de caractere (de o anumită dimensiune, acestea fiind stocate într-un vector furnizat ca parametru, începând cu o anumită poziție);​ +  * [[https://​developer.android.com/​reference/​java/​io/​BufferedReader.html#​read()|read()]] ​- pentru a primi un singur caracter (dacă este apelată fără parametrii) sau un tablou de caractere (de o anumită dimensiune, acestea fiind stocate într-un vector furnizat ca parametru, începând cu o anumită poziție);​ 
-  * ''​readLine()'' ​- pentru a primi o linie.+  * [[https://​developer.android.com/​reference/​java/​io/​BufferedReader.html#​readLine()|readLine()]] - pentru a primi o linie.
  
 <note tip>​Metoda ''​readLine()''​ este blocantă, așteptând un mesaj terminat prin ''​\n''​ (newline). În situația în care conexiunea este terminată, se transmite ''​EOF'',​ iar metoda întoarce valoarea ''​null''​.</​note>​ <note tip>​Metoda ''​readLine()''​ este blocantă, așteptând un mesaj terminat prin ''​\n''​ (newline). În situația în care conexiunea este terminată, se transmite ''​EOF'',​ iar metoda întoarce valoarea ''​null''​.</​note>​
Line 308: Line 321:
     - în clasa ''​android.os.Handler'',​ dacă se dorește accesarea mai multor controale grafice (fiind necesar ca instanțierea obiectului să fie realizată tot pe firul care gestionează interfața grafică);     - în clasa ''​android.os.Handler'',​ dacă se dorește accesarea mai multor controale grafice (fiind necesar ca instanțierea obiectului să fie realizată tot pe firul care gestionează interfața grafică);
   - folosind un obiect de tip [[http://​developer.android.com/​reference/​android/​os/​AsyncTask.html|AsyncTask]],​ procesarea în rețea putând fi realizată în metoda ''​doInBackground()'',​ iar accesul la obiectele interfeței grafice fiind acordat în metodele ''​onProgressUpdate()''​ (invocată în mod automat de fiecare dată când se apelează metoda ''​publishProgress()''​) și ''​onPostExecute()''​.   - folosind un obiect de tip [[http://​developer.android.com/​reference/​android/​os/​AsyncTask.html|AsyncTask]],​ procesarea în rețea putând fi realizată în metoda ''​doInBackground()'',​ iar accesul la obiectele interfeței grafice fiind acordat în metodele ''​onProgressUpdate()''​ (invocată în mod automat de fiecare dată când se apelează metoda ''​publishProgress()''​) și ''​onPostExecute()''​.
 +<code java>
 +// VARIANTA 1
 +   ​doInBackground{ /*** Net thread ***/
 +      socket();
 +      ... 
 +      socket.close();​
 +      return result
 +    } 
 +
 +    onPostExecute(String result) { /*** GUI thread ***/
 +      daytimeProtocolTextView.setText(result);​
 +    }
 +  ​
 +// VARIANTA 2 
 +   ​doInBackground{ /*** Net thread ***/
 +      socket..
 +      publishProgress(line); ​
 +      publishProgress(line); ​
 +      ...
 +      socket.close();​
 +      return null;
 +   ​} ​
 +   
 +    onProgressUpdate(String... progres) { /*** GUI thread ***/
 +        welcomeMessageTextView.append(progres[0] + "​\n"​);​
 +    }
 +
 +    onPostExecute(Void result) {} /*** GUI thread ***/
 +</​code>​
  
 {{ :​eim:​laboratoare:​laborator06:​fir_de_executie_dedicat_comunicatie_prin_retea.png?​nolink&​600 }} {{ :​eim:​laboratoare:​laborator06:​fir_de_executie_dedicat_comunicatie_prin_retea.png?​nolink&​600 }}
Line 317: Line 359:
 {{ :​eim:​laboratoare:​laborator06:​01day_time_protocol.png?​nolink&​400 }} {{ :​eim:​laboratoare:​laborator06:​01day_time_protocol.png?​nolink&​400 }}
  
-În acest sens, se va deschide un socket TCP, prin interogarea serverului disponibil la adresa [[time-b.nist.gov|]], pe portul 13, în cadrul unui fir de execuție separat (clasa ''​NISTCommunicationThread''​). Întrucât nu este necesară decât operația de primire a unor date, se va crea doar un obiect de tip ''​BufferedReader'',​ citindu-se două linii (una fiind vidă - așadar ignorată, cealaltă conținând informațiile necesare, care se doresc a fi afișate). Întrucât modificarea conținutului unui control grafic nu poate fi realizată decât din contextul firului de execuție în care a fost creat, acesta va fi obținut prin parametrul metodei ''​post()''​ a obiectului respectiv, doar aici fiind permisă asocierea conținutului solicitat. În momentul în care datele au fost preluate, socket-ul TCP poate fi închis. Pe fiecare eveniment de tip apăsare a butonului se va crea un fir de execuție dedicat în care se va instanția un obiect de tip ''​Socket''​.+În acest sens, se va deschide un socket TCP, prin interogarea serverului disponibil la adresa [[utcnist.colorado.edu|]], pe portul 13, în cadrul unui fir de execuție separat (clasa ''​NISTCommunicationThread''​). Întrucât nu este necesară decât operația de primire a unor date, se va crea doar un obiect de tip ''​BufferedReader'',​ citindu-se două linii (una fiind vidă - așadar ignorată, cealaltă conținând informațiile necesare, care se doresc a fi afișate). Întrucât modificarea conținutului unui control grafic nu poate fi realizată decât din contextul firului de execuție în care a fost creat, acesta va fi obținut prin parametrul metodei ''​post()''​ a obiectului respectiv, doar aici fiind permisă asocierea conținutului solicitat. În momentul în care datele au fost preluate, socket-ul TCP poate fi închis. Pe fiecare eveniment de tip apăsare a butonului se va crea un fir de execuție dedicat în care se va instanția un obiect de tip ''​Socket''​.
  
 De remarcat faptul că obiectele interfeței grafice sunt definite ca membrii protejați ai clasei activitate, întrucât accesul acestea trebuie să poată fi accesate și din clasele interne, fără a se mai obține referința către ele prin metoda ''​findViewById()'',​ care depreciază performanțele aplicației Android. De remarcat faptul că obiectele interfeței grafice sunt definite ca membrii protejați ai clasei activitate, întrucât accesul acestea trebuie să poată fi accesate și din clasele interne, fără a se mai obține referința către ele prin metoda ''​findViewById()'',​ care depreciază performanțele aplicației Android.
Line 403: Line 445:
 ==== Serverul ==== ==== Serverul ====
  
-Un sever poate "​aștepta"​ conexiuni de clienți prin intermediul unei instanțe a clasei [[http://​developer.android.com/​reference/​java/​net/​ServerSocket.html|ServerSocket]],​ care poate primi ca parametrii+Un sever poate "​aștepta"​ conexiuni de clienți prin intermediul unei instanțe a clasei [[http://​developer.android.com/​reference/​java/​net/​ServerSocket.html|ServerSocket]],​ care poate primi ca parametri
-  * o adresă ​- dacă nu este furnizată ​se folosește adresa mașinii / dispozitivului pe care a fost rulatăputând ​fi obținută prin metoda ''​getInetAddress()'';​ +  * un port - dacă nu este specificat (sau se transmite valoarea 0)sistemul de operare va genera o astfel de valoare (care poate fi obținută ​ulterior ​prin metoda ''​getLocalPort()'';​ 
-  * un port - dacă nu este specificat (sau se transmite valoarea 0), sistemul de operare va genera o astfel de valoare (care poate fi obținută ​ulterior ​prin metoda ''​getLocalPort()''​.+  * o valoare întreagă, resprezentând numărul maxim de conexiuni care pot aștepta în coadă, la un moment dat; 
 +  * o adresă ​- dacă nu este furnizată ​se folosește adresa mașinii / dispozitivului pe care a fost rulată, putând ​fi obținută prin metoda ''​getInetAddress()''​.
  
 <note tip>Se recomandă să se utilizeze un port cu o valoare în afara celor rezervate (0 - 1023). Totuși, folosirea acestor porturi este posibilă în cazul dispozitivele mobile pentru care există drepturi de root, după ce se acordă drepturi privilegiate aplicației Android.</​note>​ <note tip>Se recomandă să se utilizeze un port cu o valoare în afara celor rezervate (0 - 1023). Totuși, folosirea acestor porturi este posibilă în cazul dispozitivele mobile pentru care există drepturi de root, după ce se acordă drepturi privilegiate aplicației Android.</​note>​
Line 559: Line 602:
 {{ :​eim:​laboratoare:​laborator06:​02single_threaded_server.png?​nolink&​400 }} {{ :​eim:​laboratoare:​laborator06:​02single_threaded_server.png?​nolink&​400 }}
  
-Prin intermediul utilitarului ''​nc''​ (apelat cu adresa Internet și portul serverului) se poate interoga mesajul care a fost transmis. De asemenea, comanda ''​time''​ măsoară timpul în care a fost executată operația respectivă. +Prin intermediul utilitarului ''​nc''​ (apelat cu adresa Internet și portul serverului) se poate interoga mesajul care a fost transmis. De asemenea, comanda ''​time''​ măsoară timpul în care a fost executată operația respectivă. ​<note important>​Atenție,​ trebuie folosită versiunea nc.traditional,​ varianta nc.openbsd poate avea switch-uri diferite. Folosiți comanda <code shell>ls -l `which nc`</​code>  ​ 
 +</​note>​ pentru a afla varianta folosită implicit. ​
 <​code>​ <​code>​
-student@eim2016:~$ nc 192.168.56.101 2016+student@eim-lab:~$ nc 172.16.7.89 2000
 Hello, EIM Student! Hello, EIM Student!
-student@eim2016:~$ time nc 192.168.56.101 2016+student@eim-lab:~$ time nc 172.16.7.89 2000
 Hello, EIM Student! Hello, EIM Student!
  
Line 570: Line 613:
 user    0m0.000s user    0m0.000s
 sys     ​0m0.000s sys     ​0m0.000s
 +</​code>​
 +
 +Există și în Android o variantă simplificată de nc, care poate fi apelată folosind busybox:  ​
 +<​code>​
 +busybox nc ftp.ngc.com 21 
 +busybox nc -l -p 5000
 </​code>​ </​code>​
  
Line 663: Line 712:
 **1.** În contul Github personal, să se creeze un depozit denumit '​Laborator06'​. Inițial, acesta trebuie să fie gol (nu trebuie să bifați nici adăugarea unui fișier ''​README.md'',​ nici a fișierului ''​.gitignore''​ sau a a fișierului ''​LICENSE''​). **1.** În contul Github personal, să se creeze un depozit denumit '​Laborator06'​. Inițial, acesta trebuie să fie gol (nu trebuie să bifați nici adăugarea unui fișier ''​README.md'',​ nici a fișierului ''​.gitignore''​ sau a a fișierului ''​LICENSE''​).
  
-**2.** Să se cloneze în directorul de pe discul local conținutul depozitului la distanță de la [[https://​www.github.com/​eim2016/​Laborator06|]]. ​+**2.** Să se cloneze în directorul de pe discul local conținutul depozitului la distanță de la [[https://​www.github.com/​eim-lab/​Laborator06|]]. ​
  
 În urma acestei operații, directorul Laborator06 va trebui să se conțină directoarele ''​labtasks'',​ ''​samples''​ și ''​solutions''​. ​ În urma acestei operații, directorul Laborator06 va trebui să se conțină directoarele ''​labtasks'',​ ''​samples''​ și ''​solutions''​. ​
  
 <​code>​ <​code>​
-student@eim2016:~$ git clone https://​www.github.com/​eim2016/​Laborator06.git+student@eim:~$ git clone https://​www.github.com/​eim-lab/​Laborator06.git
 </​code>​ </​code>​
  
 **3.** Să se încarce conținutul descărcat în cadrul depozitului '​Laborator06'​ de pe contul Github personal. <​code>​ **3.** Să se încarce conținutul descărcat în cadrul depozitului '​Laborator06'​ de pe contul Github personal. <​code>​
-student@eim2016:~$ cd Laborator06 +student@eim:~$ cd Laborator06 
-student@eim2016:​~/​Laborator06$ git remote add Laborator06_perfectstudent https://​github.com/​perfectstudent/​Laborator06 +student@eim:​~/​Laborator06$ git remote add Laborator06_perfectstudent https://​github.com/​perfectstudent/​Laborator06 
-student@eim2016:​~/​Laborator06$ git push Laborator06_perfectstudent master+student@eim:​~/​Laborator06$ git push Laborator06_perfectstudent master
 </​code>​ </​code>​
  
-**4.** Să se importe în mediul integrat de dezvoltare ​preferat (Android Studio ​sau Eclipse) ​proiectul ''​FTPServerWelcomeMessage''​ din directorul ''​labtasks''​.+**4.** Să se importe în mediul integrat de dezvoltare Android Studio proiectul ''​FTPServerWelcomeMessage''​ din directorul ''​labtasks''​.
  
 Se cere să se implementeze o aplicație Android care citește mesajul de întâmpinare transmis în momentul în care se realizează o conexiune către un server FTP.  Se cere să se implementeze o aplicație Android care citește mesajul de întâmpinare transmis în momentul în care se realizează o conexiune către un server FTP. 
Line 685: Line 734:
 În cazul în care mesajul de întâmpinare conține mai multe linii, mesajul este precedat de șirul de caractere ''​220-''​ (reținut în ''​Constants.FTP_MULTILINE_START_CODE''​). Mesajul se încheie fie cu șirul de caractere ''​220'',​ fie cu un șir de caractere precedat de ''​220 ''​ (valori stocate în ''​Constants.FTP_MULTILINE_END_CODE1'',​ respectiv ''​Constants.FTP_MULTILINE_END_CODE2''​). În cazul în care mesajul de întâmpinare conține mai multe linii, mesajul este precedat de șirul de caractere ''​220-''​ (reținut în ''​Constants.FTP_MULTILINE_START_CODE''​). Mesajul se încheie fie cu șirul de caractere ''​220'',​ fie cu un șir de caractere precedat de ''​220 ''​ (valori stocate în ''​Constants.FTP_MULTILINE_END_CODE1'',​ respectiv ''​Constants.FTP_MULTILINE_END_CODE2''​).
  
-{{ :​eim:​laboratoare:​laborator06:​03ftp_server_welcome_message.png?​nolink&​400 }}+{{ :​eim:​laboratoare:​ex5_ftp_image.png?​nolink&​400 }}
  
 Operațiile care trebuie realizate pe metoda ''​doInBackground()''​ a firului de execuție ce gestionează comunicația cu serverul FTP sunt: Operațiile care trebuie realizate pe metoda ''​doInBackground()''​ a firului de execuție ce gestionează comunicația cu serverul FTP sunt:
Line 701: Line 750:
   - închiderea socket-ului.   - închiderea socket-ului.
  
-Să se verifice mesajul afișat în momentul în care se realizează o conexiune la serverul [[ftp.ngc.com|]].+Să se verifice mesajul afișat în momentul în care se realizează o conexiune la serverul [[intranet.ngcaerospace.com/|]].
  
-**5.** Să se importe în mediul integrat de dezvoltare ​preferat (Android Studio ​sau Eclipse) ​proiectul ''​SingleThreadedServer''​ din directorul ''​labtasks''​.+**5.** Să se importe în mediul integrat de dezvoltare Android Studio proiectul ''​SingleThreadedServer''​ din directorul ''​labtasks''​.
  
-Acesta reprezintă o aplicație Android care implementează un server ce ascultă pe un port (2016, în ''​Constants.SERVER_PORT''​) solicitări de conexiune provenite de la clienți.+Acesta reprezintă o aplicație Android care implementează un server ce ascultă pe un port (2000, în ''​Constants.SERVER_PORT''​) solicitări de conexiune provenite de la clienți.
  
 Pe același fir de execuție pe care se face așteptarea,​ este realizată și transmiterea mesajului către client, preluat dintr-un câmp text. Pe același fir de execuție pe care se face așteptarea,​ este realizată și transmiterea mesajului către client, preluat dintr-un câmp text.
Line 720: Line 769:
  
 <​code>​ <​code>​
-student@eim2016:~$ nc 192.168.56.101 2016+student@eim-lab:~$ nc 172.16.7.89 2000
 Hello, EIM Student! Hello, EIM Student!
-student@eim2016:~$ time nc 192.168.56.101 2016+student@eim-lab:~$ time nc 172.16.7.89 2000
 Hello, EIM Student! Hello, EIM Student!
  
Line 747: Line 796:
  
 <​code>​ <​code>​
-C:​\Users\Student>​ telnet 192.168.56.101 ​2016+C:​\Users\Student>​ telnet 192.168.56.101 ​2000
 Start Server Start Server
  
 Connection to host lost. Connection to host lost.
-C:​\Users\Student>​ telnet 192.168.56.101 ​2016 +C:​\Users\Student>​ telnet 192.168.56.101 ​2000 
-Connecting To 192.168.56.101...Could not open connection to the host, on port 2016: Connect failed+Connecting To 192.168.56.101...Could not open connection to the host, on port 2000: Connect failed
 </​code>​ </​code>​
  
Line 761: Line 810:
 **b)** Să se apese tasta //Back//. De ce sunt tratate cererile în continuare după ce aplicația Android este distrusă? Ce se întâmplă în momentul în care se dorește să se repornească aplicația Android? Cum ar putea fi remediată această problemă? **b)** Să se apese tasta //Back//. De ce sunt tratate cererile în continuare după ce aplicația Android este distrusă? Ce se întâmplă în momentul în care se dorește să se repornească aplicația Android? Cum ar putea fi remediată această problemă?
  
 +<spoiler Indicații de Rezolvare>​
 Aplicația Android este distrusă, însă resursele utilizate de acestea nu sunt eliberate, motiv pentru care serverul continuă să gestioneze solicitările primite de la clienți. Aplicația Android este distrusă, însă resursele utilizate de acestea nu sunt eliberate, motiv pentru care serverul continuă să gestioneze solicitările primite de la clienți.
  
Line 779: Line 829:
 @Override @Override
 public void onDestroy() { public void onDestroy() {
-  super.onDestroy();​ 
   if (serverThread != null) {   if (serverThread != null) {
     serverThread.stopServer();​     serverThread.stopServer();​
   }   }
 +  super.onDestroy();​
 } }
 </​code>​ </​code>​
 +</​spoiler>​
  
 **c)** Să se simuleze faptul că operația de comunicare dintre client și server durează o perioadă de timp mai mare (spre exemplu, 3 secunde). Ce se întâmplă în momentul în care există mai multe solicitări trimise simultan de mai mulți clienți (din console diferite)? Monitorizați timpul de răspuns în această situație. **c)** Să se simuleze faptul că operația de comunicare dintre client și server durează o perioadă de timp mai mare (spre exemplu, 3 secunde). Ce se întâmplă în momentul în care există mai multe solicitări trimise simultan de mai mulți clienți (din console diferite)? Monitorizați timpul de răspuns în această situație.
  
 +<spoiler Indicații de Rezolvare>​
 Metoda ''​Thread.sleep()'',​ primind ca parametru un interval de timp (exprimat în milisecunde) simulează o așteptare, după care execuția aplicației Android este reluată în mod normal. Metoda ''​Thread.sleep()'',​ primind ca parametru un interval de timp (exprimat în milisecunde) simulează o așteptare, după care execuția aplicației Android este reluată în mod normal.
  
Line 800: Line 852:
 } }
 </​code>​ </​code>​
 +</​spoiler>​
  
 **d)** Să se implementeze comunicația pentru fiecare conexiune dintre client și server pe un fir de execuție separat, astfel încât pe server, gestiunea solicitărilor provenite de la clienți să nu fie afectată. **d)** Să se implementeze comunicația pentru fiecare conexiune dintre client și server pe un fir de execuție separat, astfel încât pe server, gestiunea solicitărilor provenite de la clienți să nu fie afectată.
  
-**6.** Să se importe în mediul integrat de dezvoltare ​preferat (Android Studio ​sau Eclipse) ​proiectul ''​ClientServerCommunication''​ din directorul ''​labtasks''​.+**6.** Să se importe în mediul integrat de dezvoltare Android Studio proiectul ''​ClientServerCommunication''​ din directorul ''​labtasks''​.
  
 Acesta reprezintă o aplicație Android având două fragmente, implementând atât un server cât și un client: Acesta reprezintă o aplicație Android având două fragmente, implementând atât un server cât și un client:
Line 817: Line 870:
 **a)** Să se implementeze funcționalitatea serverului. **a)** Să se implementeze funcționalitatea serverului.
  
-În clasa ''​ComunicationThread'' ​din fragmentul asociat serverului:+În clasa ''​ComunicationThread'':​
   - se obține o referință către fluxul de ieșire asociat socket-ului,​ prin intermediul metodei ajutătoare ''​Utilities.getWriter()'';​   - se obține o referință către fluxul de ieșire asociat socket-ului,​ prin intermediul metodei ajutătoare ''​Utilities.getWriter()'';​
   - se scrie o linie conținând textul din ''​serverTextEditText''​.   - se scrie o linie conținând textul din ''​serverTextEditText''​.
Line 823: Line 876:
 **b)** Să se implementeze funcționalitatea clientului. **b)** Să se implementeze funcționalitatea clientului.
  
-În clasa ''​ClientAsyncTask'' ​din fragmentul asociat serverului:+În clasa ''​ClientAsyncTask'':​
   - se resetează conținutul câmpului text ''​serverMessageTextView'',​ astfel încât acesta să conțină șirul vid; acest lucru este realizat înainte de a rula firul de execuție dedicat, așadar pe metoda ''​onPreExecute()'';​   - se resetează conținutul câmpului text ''​serverMessageTextView'',​ astfel încât acesta să conțină șirul vid; acest lucru este realizat înainte de a rula firul de execuție dedicat, așadar pe metoda ''​onPreExecute()'';​
   - se obțin parametrii de conexiune la server (adresa de Internet, obținută din câmpul text ''​serverAddressEditText''​ și portul, obținut din câmpul text ''​serverPortEditText''​);​ aceștia sunt transmiși prin intermediul argumentelor metodei ''​doInBackground()'';​   - se obțin parametrii de conexiune la server (adresa de Internet, obținută din câmpul text ''​serverAddressEditText''​ și portul, obținut din câmpul text ''​serverPortEditText''​);​ aceștia sunt transmiși prin intermediul argumentelor metodei ''​doInBackground()'';​
Line 833: Line 886:
 <note important>​Accesul la controalele grafice trebuie să fie realizat numai din contextul firului de execuție asociat interfeței cu utilizatorul.</​note>​ <note important>​Accesul la controalele grafice trebuie să fie realizat numai din contextul firului de execuție asociat interfeței cu utilizatorul.</​note>​
  
-**c)** Să se pornească serverul (se introduce textul //Start Server//). În client, să se verifice valoarea furnizată în cazul în care se introduc valorile ''​127.0.0.1''​ / ''​2016'',​ respectiv ''​localhost''​ / ''​2016''​. ​+**c)** Să se pornească serverul (se introduce textul //Start Server//). În client, să se verifice valoarea furnizată în cazul în care se introduc valorile ''​127.0.0.1''​ / ''​2000'',​ respectiv ''​localhost''​ / ''​2000''​. ​
  
 Să se oprească serverul (se introduce textul //Stop Server//). Să se verifice ce valori sunt furnizate în această situație. Să se oprească serverul (se introduce textul //Stop Server//). Să se verifice ce valori sunt furnizate în această situație.
  
-**d)** (doar Linux) Să se creeze o listă cu procesele care rulează la momentul curent, textul putând fi obținut, linie cu linie, prin intermediul unei conexiuni pe portul ​2016, serverul fiind astfel simulat pe mașina fizică.+**d)** (doar Linux) Să se creeze o listă cu procesele care rulează la momentul curent, textul putând fi obținut, linie cu linie, prin intermediul unei conexiuni pe portul ​2000, serverul fiind astfel simulat pe mașina fizică.
  
 <​code>​ <​code>​
-student@eim2016:~$ ps a | while read x; do echo "​$x"​ | nc -l 2016; done+student@eim:~$ ps a | while read x; do echo "​$x"​ | nc -l 2000; done
 </​code>​ </​code>​
  
 <note tip>Pe mașinile Debian, comanda ''​nc''​ se rulează cu opțiunea suplimentară ''​-p''​ pentru a se indica portul pe care se dorește ca acesta să accepte invocările.</​note>​ <note tip>Pe mașinile Debian, comanda ''​nc''​ se rulează cu opțiunea suplimentară ''​-p''​ pentru a se indica portul pe care se dorește ca acesta să accepte invocările.</​note>​
  
-Să se folosească clientul pentru a citi, linie cu linie, valorile furnizate de script-ul anterior. Va trebui precizată adresa mașinii fizice (în funcție de configurația folosită) și portul ​2016.+Să se folosească clientul pentru a citi, linie cu linie, valorile furnizate de script-ul anterior. Va trebui precizată adresa mașinii fizice (în funcție de configurația folosită) și portul ​2000
  
 {{ :​eim:​laboratoare:​laborator06:​05client_server_communication.png?​nolink&​400 }} {{ :​eim:​laboratoare:​laborator06:​05client_server_communication.png?​nolink&​400 }}
  
-**7.** Să se importe în mediul integrat de dezvoltare ​preferat (Android Studio ​sau Eclipse) ​proiectul ''​PheasantGame''​ din directorul ''​labtasks''​.+ 
 +==== Homework (due next week) ==== 
 +**7.** Să se importe în mediul integrat de dezvoltare Android Studio proiectul ''​PheasantGame''​ din directorul ''​labtasks''​.
  
 Acesta reprezintă o aplicație Android care implementează jocul Fazan în limba engleză, atât partea de server, cât și partea de client. Acesta reprezintă o aplicație Android care implementează jocul Fazan în limba engleză, atât partea de server, cât și partea de client.
Line 889: Line 944:
  
 **8.** ​ Să se încarce modificările realizate în cadrul depozitului '​Laborator06'​ de pe contul Github personal, folosind un mesaj sugestiv. <​code>​ **8.** ​ Să se încarce modificările realizate în cadrul depozitului '​Laborator06'​ de pe contul Github personal, folosind un mesaj sugestiv. <​code>​
-student@eim2016:​~/​Laborator06$ git add * +student@eim:​~/​Laborator06$ git add * 
-student@eim2016:​~/​Laborator06$ git commit -m "​implemented taks for laboratory 06" +student@eim:​~/​Laborator06$ git commit -m "​implemented taks for laboratory 06" 
-student@eim2016:​~/​Laborator06$ git push Laborator02_perfectstudent master+student@eim:​~/​Laborator06$ git push Laborator02_perfectstudent master
 </​code>​ </​code>​
  
eim/laboratoare/laborator06.1460089046.txt.gz · Last modified: 2016/04/08 07:17 by tmp.andrei.cojocaru
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0