Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
|
laboratoare:laborator06 [2015/04/06 16:24] Andrei Roșu-Cojocaru |
laboratoare:laborator06 [2017/02/20 20:54] (current) |
||
|---|---|---|---|
| Line 19: | Line 19: | ||
| <code> | <code> | ||
| - | student@pdsd2015:/opt/android-sdk-linux/platform-tools$ ./adb devices | + | student@eim2016:/opt/android-sdk-linux/platform-tools$ ./adb devices |
| List of devices attached | List of devices attached | ||
| 0019531d59461f device | 0019531d59461f device | ||
| - | student@pdsd2015:/opt/android-sdk-linux/platform-tools$ ./adb -s 0019531d59461f shell | + | student@eim2016:/opt/android-sdk-linux/platform-tools$ ./adb -s 0019531d59461f shell |
| shell@n7000:/ $ su | shell@n7000:/ $ su | ||
| su | su | ||
| Line 33: | Line 33: | ||
| <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@pdsd2015:/opt/android-sdk-linux/platform-tools$ ./adb devices | + | student@eim2016:/opt/android-sdk-linux/platform-tools$ ./adb devices |
| List of devices attached | List of devices attached | ||
| 0019531d59461f ???????????? | 0019531d59461f ???????????? | ||
| - | student@pdsd2015:/opt/android-sdk-linux/platform-tools$ sudo ./adb kill-server | + | student@eim2016:/opt/android-sdk-linux/platform-tools$ sudo ./adb kill-server |
| - | student@pdsd2015:/opt/android-sdk-linux/platform-tools$ sudo ./adb start-server | + | student@eim2016:/opt/android-sdk-linux/platform-tools$ sudo ./adb start-server |
| - | student@pdsd2015:/opt/android-sdk-linux/platform-tools$ sudo ./adb devices | + | student@eim2016:/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. | ||
| 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 53: | Line 55: | ||
| <code> | <code> | ||
| - | student@pdsd2015:~$ sudo ifconfig usb0 | + | student@eim2016:~$ 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 103: | Line 105: | ||
| 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@pdsd2015:/opt/android-sdk-linux/platform-tools$ ./adb devices | + | student@eim2016:/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 | ||
| </code> | </code> | ||
| - | * prin intermediul plugin-ului Genymotion pentru mediul integrat de dezvoltare Eclipse Luna SR1a (4.4.1) - Ctrl + 6. | + | * prin intermediul plugin-ului Genymotion pentru mediile integrate de dezvoltare. |
| {{ :laboratoare:laborator06:genymotion_ip_addresses.png?nolink&700 }} | {{ :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 fizică și dispozitivul virtual poate fi verificată folosind comanda ''ping''. <code> | ||
| - | student@pdsd2015:~$ ping 192.168.56.101 | + | student@eim2016:~$ 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 137: | Line 139: | ||
| * prin rularea comenzii ''adb devices'' <code> | * prin rularea comenzii ''adb devices'' <code> | ||
| - | student@pdsd2015:/opt/android-sdk-linux/platform-tools$ ./adb devices | + | student@eim2016:/opt/android-sdk-linux/platform-tools$ ./adb devices |
| List of devices attached | List of devices attached | ||
| emulator-5554 device | emulator-5554 device | ||
| Line 143: | Line 145: | ||
| Conectarea la consola dispozitivului virtual Android se face prin comanda: <code> | Conectarea la consola dispozitivului virtual Android se face prin comanda: <code> | ||
| - | student@pdsd2015:~$ telnet localhost 55nr | + | student@eim2016:~$ 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: | + | Î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 160: | Line 162: | ||
| <code> | <code> | ||
| - | student@pdsd2015:~$ telnet localhost 5554 | + | student@eim2016:~$ telnet localhost 5554 |
| Android Console: type 'help' for a list of commands | Android Console: type 'help' for a list of commands | ||
| OK | OK | ||
| Line 175: | Line 177: | ||
| exit | exit | ||
| Connection to host lost. | Connection to host lost. | ||
| - | student@pdsd2015:~$ | + | student@eim2016:~$ |
| </code> | </code> | ||
| Line 218: | Line 220: | ||
| <code java> | <code java> | ||
| String hostname = "localhost"; | String hostname = "localhost"; | ||
| - | int port = 2015; | + | int port = 2016; |
| Socket socket = new Socket(hostname, port); | Socket socket = new Socket(hostname, port); | ||
| </code> | </code> | ||
| Line 313: | Line 315: | ||
| Se dorește interogarea serverului National Institute of Standards & Technology, care oferă un serviciu de interogare a datei și orei curente, cu o precizie ridicată, conform [[https://tools.ietf.org/html/rfc867|Daytime Protocol (RFC-867)]]. | Se dorește interogarea serverului National Institute of Standards & Technology, care oferă un serviciu de interogare a datei și orei curente, cu o precizie ridicată, conform [[https://tools.ietf.org/html/rfc867|Daytime Protocol (RFC-867)]]. | ||
| - | {{ :laboratoare:laborator06:daytime_protocol.png?nolink&400 }} | + | {{ :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 [[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''. | ||
| Line 319: | Line 321: | ||
| 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. | ||
| - | <file java DaytimeProtocol.java> | + | <file java DayTimeProtocolActivity.java> |
| - | import java.io.BufferedReader; | + | package ro.pub.cs.systems.eim.lab06.daytimeprotocol.views; |
| - | import java.io.IOException; | + | |
| - | import java.net.Socket; | + | |
| - | import java.net.UnknownHostException; | + | |
| - | import android.app.Activity; | + | import android.os.AsyncTask; |
| + | import android.support.v7.app.AppCompatActivity; | ||
| import android.os.Bundle; | import android.os.Bundle; | ||
| import android.util.Log; | import android.util.Log; | ||
| - | import android.view.Menu; | ||
| - | import android.view.MenuItem; | ||
| import android.view.View; | import android.view.View; | ||
| import android.widget.Button; | import android.widget.Button; | ||
| import android.widget.TextView; | import android.widget.TextView; | ||
| - | public class DaytimeProtocolActivity extends Activity { | + | import java.io.BufferedReader; |
| + | import java.io.IOException; | ||
| + | import java.net.Socket; | ||
| + | import java.net.UnknownHostException; | ||
| + | |||
| + | import ro.pub.cs.systems.eim.lab06.daytimeprotocol.R; | ||
| + | import ro.pub.cs.systems.eim.lab06.daytimeprotocol.general.Constants; | ||
| + | import ro.pub.cs.systems.eim.lab06.daytimeprotocol.general.Utilities; | ||
| + | |||
| + | public class DayTimeProtocolActivity extends AppCompatActivity { | ||
| + | |||
| + | private Button getInformationButton; | ||
| + | private TextView daytimeProtocolTextView; | ||
| + | |||
| + | private class NISTCommunicationAsyncTask extends AsyncTask<Void, Void, String> { | ||
| - | protected Button getInformationButton; | ||
| - | protected TextView daytimeProtocolTextView; | ||
| - | |||
| - | protected class NISTCommunicationThread extends Thread { | ||
| - | | ||
| @Override | @Override | ||
| - | public void run() { | + | protected String doInBackground(Void... params) { |
| + | String dayTimeProtocol = null; | ||
| try { | try { | ||
| - | Socket socket = new Socket ( | + | Socket socket = new Socket(Constants.NIST_SERVER_HOST, Constants.NIST_SERVER_PORT); |
| - | Constants.NIST_SERVER_HOST, | + | |
| - | Constants.NIST_SERVER_PORT | + | |
| - | ); | + | |
| BufferedReader bufferedReader = Utilities.getReader(socket); | BufferedReader bufferedReader = Utilities.getReader(socket); | ||
| bufferedReader.readLine(); | bufferedReader.readLine(); | ||
| - | final String daytimeProtocol = bufferedReader.readLine(); | + | dayTimeProtocol = bufferedReader.readLine(); |
| - | daytimeProtocolTextView.post(new Runnable() { | + | Log.d(Constants.TAG, "The server returned: " + dayTimeProtocol); |
| - | @Override | + | |
| - | public void run() { | + | |
| - | daytimeProtocolTextView.setText(daytimeProtocol); | + | |
| - | } | + | |
| - | }); | + | |
| - | socket.close(); | + | |
| } catch (UnknownHostException unknownHostException) { | } catch (UnknownHostException unknownHostException) { | ||
| - | Log.e(Constants.TAG, "An exception has occurred: "+unknownHostException.getMessage()); | + | Log.d(Constants.TAG, unknownHostException.getMessage()); |
| - | if (Constants.DEBUG) { | + | if (Constants.DEBUG) { |
| unknownHostException.printStackTrace(); | unknownHostException.printStackTrace(); | ||
| } | } | ||
| } catch (IOException ioException) { | } catch (IOException ioException) { | ||
| - | Log.e(Constants.TAG, "An exception has occurred: "+ioException.getMessage()); | + | Log.d(Constants.TAG, ioException.getMessage()); |
| if (Constants.DEBUG) { | if (Constants.DEBUG) { | ||
| ioException.printStackTrace(); | ioException.printStackTrace(); | ||
| } | } | ||
| } | } | ||
| + | return dayTimeProtocol; | ||
| + | } | ||
| + | |||
| + | @Override | ||
| + | protected void onPostExecute(String result) { | ||
| + | daytimeProtocolTextView.setText(result); | ||
| } | } | ||
| } | } | ||
| - | | + | |
| - | protected ButtonClickListener buttonClickListener = new ButtonClickListener(); | + | private ButtonClickListener buttonClickListener = new ButtonClickListener(); |
| - | | + | private class ButtonClickListener implements Button.OnClickListener { |
| - | protected class ButtonClickListener implements Button.OnClickListener { | + | |
| - | + | ||
| @Override | @Override | ||
| public void onClick(View view) { | public void onClick(View view) { | ||
| - | new NISTCommunicationThread().start(); | + | NISTCommunicationAsyncTask nistCommunicationAsyncTask = new NISTCommunicationAsyncTask(); |
| + | nistCommunicationAsyncTask.execute(); | ||
| } | } | ||
| + | |||
| } | } | ||
| - | | + | |
| @Override | @Override | ||
| protected void onCreate(Bundle savedInstanceState) { | protected void onCreate(Bundle savedInstanceState) { | ||
| super.onCreate(savedInstanceState); | super.onCreate(savedInstanceState); | ||
| - | setContentView(R.layout.activity_daytime_protocol); | + | setContentView(R.layout.activity_day_time_protocol); |
| - | + | ||
| daytimeProtocolTextView = (TextView)findViewById(R.id.daytime_protocol_text_view); | daytimeProtocolTextView = (TextView)findViewById(R.id.daytime_protocol_text_view); | ||
| - | | + | |
| getInformationButton = (Button)findViewById(R.id.get_information_button); | getInformationButton = (Button)findViewById(R.id.get_information_button); | ||
| getInformationButton.setOnClickListener(buttonClickListener); | getInformationButton.setOnClickListener(buttonClickListener); | ||
| Line 425: | Line 431: | ||
| android:layout_height="match_parent" | android:layout_height="match_parent" | ||
| android:orientation="vertical" | android:orientation="vertical" | ||
| - | tools:context="ro.pub.cs.systems.pdsd.lab06.singlethreadedserver.views.SingleThreadedActivity" > | + | tools:context="ro.pub.cs.systems.eim.lab06.singlethreadedserver.views.SingleThreadedActivity" > |
| | | ||
| <EditText | <EditText | ||
| Line 551: | Line 557: | ||
| </file> | </file> | ||
| - | {{ :laboratoare:laborator06:single_threaded_server.png?nolink&400 }} | + | {{ :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ă. | ||
| <code> | <code> | ||
| - | student@pdsd2015:~$ nc 192.168.56.101 2015 | + | student@eim2016:~$ nc 192.168.56.101 2016 |
| - | Hello, PDSD Student! | + | Hello, EIM Student! |
| - | student@pdsd2015:~$ time nc 192.168.56.101 2015 | + | student@eim2016:~$ time nc 192.168.56.101 2016 |
| - | Hello, PDSD Student! | + | Hello, EIM Student! |
| real 0m0.009s | real 0m0.009s | ||
| Line 657: | Line 663: | ||
| **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/pdsd2015/Laborator06|]]. | + | **2.** Să se cloneze în directorul de pe discul local conținutul depozitului la distanță de la [[https://www.github.com/eim2016/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@pdsd2015:~$ git clone https://www.github.com/pdsd2015/Laborator06 | + | student@eim2016:~$ git clone https://www.github.com/eim2016/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@pdsd2015:~$ cd Laborator06 | + | student@eim2016:~$ cd Laborator06 |
| - | student@pdsd2015:~/Laborator06$ git remote add Laborator06_perfectstudent https://github.com/perfectstudent/Laborator06 | + | student@eim2016:~/Laborator06$ git remote add Laborator06_perfectstudent https://github.com/perfectstudent/Laborator06 |
| - | student@pdsd2015:~/Laborator06$ git push Laborator06_perfectstudent master | + | student@eim2016:~/Laborator06$ git push Laborator06_perfectstudent master |
| </code> | </code> | ||
| - | **4.** Să se importe în mediul integrat de dezvoltare Eclipse Luna SR1a (4.4.1) proiectul ''01-FTPServerWelcomeMessage'' din directorul ''labtasks''. | + | **4.** Să se importe în mediul integrat de dezvoltare preferat (Android Studio sau Eclipse) 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 679: | Line 685: | ||
| Î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''). | ||
| - | {{ :laboratoare:laborator06:ftp_server_welcome_message.png?nolink&400 }} | + | {{ :laboratoare:laborator06:03ftp_server_welcome_message.png?nolink&400 }} |
| - | Operațiile care trebuie realizate pe metoda ''run()'' 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: |
| - deschiderea unui socket care primește ca parametrii: | - deschiderea unui socket care primește ca parametrii: | ||
| - | - adresa Internet a serverului FTP (precizată anterior de utilizator, preluată din câmpul text ''FTPServerAddressEditText'') | + | - adresa Internet a serverului FTP (precizată anterior de utilizator, preluată din câmpul text ''FTPServerAddressEditText'', transmis ca parametru al metodei - ''params[0]'') |
| - portul 21 (preluat din ''Constants.FTP_PORT''). | - portul 21 (preluat din ''Constants.FTP_PORT''). | ||
| - obținerea fluxului de intrare atașat socket-ului, printr-un apel al metodei ''Utilities.getBufferedReader()''; | - obținerea fluxului de intrare atașat socket-ului, printr-un apel al metodei ''Utilities.getBufferedReader()''; | ||
| Line 691: | Line 697: | ||
| - nu este egală cu ''220'' (preluat din ''Constants.FTP_MULTILINE_END_CODE1''); | - nu este egală cu ''220'' (preluat din ''Constants.FTP_MULTILINE_END_CODE1''); | ||
| - nu începe cu ''220 '' (preluat din ''Constants.FTP_MULTILINE_END_CODE2''); | - nu începe cu ''220 '' (preluat din ''Constants.FTP_MULTILINE_END_CODE2''); | ||
| - | - valoarea primită de la serverul FTP este inclusă în câmpul text ''welcomeMEssageTextView''; | + | - valoarea primită de la serverul FTP este inclusă în câmpul text ''welcomeMEssageTextView'' (informația se transmite, pe măsură ce este primită, prin metoda ''publishProgress()'' care face să se invoce automat metoda de callback ''onProgressUpdate()'' executată pe firul de execuție principal al aplicației Android, la care se oferă acces la controalele grafice); |
| - altfel, mesajul este ignorat. | - altfel, mesajul este ignorat. | ||
| - î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 [[ftp.ngc.com|]]. |
| - | **5.** Să se importe în mediul integrat de dezvoltare Eclipse Luna SR1a (4.4.1) proiectul ''02-SingleThreadedServer'' din directorul ''labtasks''. | + | **5.** Să se importe în mediul integrat de dezvoltare preferat (Android Studio sau Eclipse) proiectul ''SingleThreadedServer'' din directorul ''labtasks''. |
| - | Acesta reprezintă o aplicație Android care implementează un server ce ascultă pe un port (2015, î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 (2016, î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 709: | Line 715: | ||
| Preluarea invocărilor de la clienți este realizată doar atâta timp cât serverul se află în execuție. | Preluarea invocărilor de la clienți este realizată doar atâta timp cât serverul se află în execuție. | ||
| - | === | + | ==== Linux ==== |
| - | + | ||
| - | **Linux** | + | |
| Citirea mesajelor se face cu ''nc'' care primește ca parametrii adresa Internet și portul serverului de pe dispozitivul Android. Prin utilitarul ''time'' se verifică durata operației respective. | Citirea mesajelor se face cu ''nc'' care primește ca parametrii adresa Internet și portul serverului de pe dispozitivul Android. Prin utilitarul ''time'' se verifică durata operației respective. | ||
| <code> | <code> | ||
| - | student@pdsd2015:~$ nc 192.168.56.101 2015 | + | student@eim2016:~$ nc 192.168.56.101 2016 |
| - | Hello, PDSD Student! | + | Hello, EIM Student! |
| - | student@pdsd2015:~$ time nc 192.168.56.101 2015 | + | student@eim2016:~$ time nc 192.168.56.101 2016 |
| - | Hello, PDSD Student! | + | Hello, EIM Student! |
| real 0m0.009s | real 0m0.009s | ||
| Line 726: | Line 730: | ||
| </code> | </code> | ||
| - | **Windows** | + | ==== Windows ==== |
| Citirea mesajelor se face cu ''telnet'' care primește ca parametrii adresa Internet și portul serverului de pe dispozitivul Android. | Citirea mesajelor se face cu ''telnet'' care primește ca parametrii adresa Internet și portul serverului de pe dispozitivul Android. | ||
| Line 743: | Line 747: | ||
| <code> | <code> | ||
| - | C:\Users\Student> telnet 192.168.56.101 2015 | + | C:\Users\Student> telnet 192.168.56.101 2016 |
| Start Server | Start Server | ||
| Connection to host lost. | Connection to host lost. | ||
| - | C:\Users\Student> telnet 192.168.56.101 2015 | + | C:\Users\Student> telnet 192.168.56.101 2016 |
| - | Connecting To 192.168.56.101...Could not open connection to the host, on port 2015: Connect failed | + | Connecting To 192.168.56.101...Could not open connection to the host, on port 2016: Connect failed |
| </code> | </code> | ||
| - | === | + | ===== ===== |
| **a)** Să se trimită aplicația Android în fundal prin apăsarea tastei //Home//. Verificați conectivitatea cu serverul. De ce sunt tratate cererile în continuare? | **a)** Să se trimită aplicația Android în fundal prin apăsarea tastei //Home//. Verificați conectivitatea cu serverul. De ce sunt tratate cererile în continuare? | ||
| Line 776: | Line 780: | ||
| public void onDestroy() { | public void onDestroy() { | ||
| super.onDestroy(); | super.onDestroy(); | ||
| - | serverThread.stopServer(); | + | if (serverThread != null) { |
| + | serverThread.stopServer(); | ||
| + | } | ||
| } | } | ||
| </code> | </code> | ||
| Line 797: | Line 803: | ||
| **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 Eclipse Luna SR1a (4.4.1) proiectul ''03-ClientServerCommunication'' din directorul ''labtasks''. | + | **6.** Să se importe în mediul integrat de dezvoltare preferat (Android Studio sau Eclipse) 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 807: | Line 813: | ||
| - clientul dispune de două câmpuri text, prin care se precizează parametrii de conexiune la server (adresa de Internet / portul) precum și un buton prin intermediul căruia se realizează legătura propriu-zisă, fiind preluată informația din cadrul canalului de comunicație și afișată corespunzător. | - clientul dispune de două câmpuri text, prin care se precizează parametrii de conexiune la server (adresa de Internet / portul) precum și un buton prin intermediul căruia se realizează legătura propriu-zisă, fiind preluată informația din cadrul canalului de comunicație și afișată corespunzător. | ||
| - | {{ :laboratoare:laborator06:client_server_communication01.png?nolink&400 }} | + | {{ :laboratoare:laborator06:04client_server_communication.png?nolink&400 }} |
| **a)** Să se implementeze funcționalitatea serverului. | **a)** Să se implementeze funcționalitatea serverului. | ||
| Line 817: | Line 823: | ||
| **b)** Să se implementeze funcționalitatea clientului. | **b)** Să se implementeze funcționalitatea clientului. | ||
| - | În clasa ''ClientThread'' din fragmentul asociat serverului: | + | În clasa ''ClientAsyncTask'' din fragmentul asociat serverului: |
| - | - se resetează conținutul câmpului text ''serverMessageTextView'', astfel încât acesta să conțină șirul vid; | + | - 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''); | + | - 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 deschide un socket, folosind configurația precizată de utilizator; | - se deschide un socket, folosind configurația precizată de utilizator; | ||
| - se obține o referință către fluxul de intrare asociat socket-ului, prin intermediul metodei ajutătoare ''Utilities.getReader()''; | - se obține o referință către fluxul de intrare asociat socket-ului, prin intermediul metodei ajutătoare ''Utilities.getReader()''; | ||
| - | - se citesc linii din contextul canalului de comunicație, atâta timp cât nu se întâlnește ''EOF'' (nu se întoarce valoarea ''null''), valoarea fiind concatenată la câmpul text ''serverMessageTextView''; | + | - se citesc linii din contextul canalului de comunicație, atâta timp cât nu se întâlnește ''EOF'' (nu se întoarce valoarea ''null''), valoarea fiind concatenată la câmpul text ''serverMessageTextView''; acest lucru este realizat prin transmiterea liniilor către firul de execuție principal - al interfeței grafice - (unde controalele grafice sunt accesibile), prin intermediul metodei ''publishProgress()'' care determină apelul metodei de callback ''onPublishProgress()''; |
| - se închide socketul. | - se închide socketul. | ||
| <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'' / ''2015'', respectiv ''localhost'' / ''2015''. | + | **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''. |
| 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 2015, 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 2016, serverul fiind astfel simulat pe mașina fizică. |
| <code> | <code> | ||
| - | student@pdsd2015:~$ ps a | while read x; do echo "$x" | nc -l 2015; done | + | student@eim2016:~$ ps a | while read x; do echo "$x" | nc -l 2016; done |
| </code> | </code> | ||
| - | 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 2015. | + | <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> |
| - | {{ :laboratoare:laborator06:client_server_communication02.png?nolink&400 }} | + | 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. |
| - | **7.** Să se importe în mediul integrat de dezvoltare Eclipse Luna SR1a (4.4.1) proiectul ''04-PheasantGame'' din directorul ''labtasks''. | + | {{ :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''. | ||
| 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 853: | Line 861: | ||
| - altfel, se trimite înapoi cuvântul primit pentru a semnala faptul că există o problemă. | - altfel, se trimite înapoi cuvântul primit pentru a semnala faptul că există o problemă. | ||
| - | {{ :laboratoare:laborator06:pheasant_game.png?nolink&400 }} | + | {{ :laboratoare:laborator06:06pheasant_game.png?nolink&400 }} |
| Astfel, serverul va avea următoarea funcționare: | Astfel, serverul va avea următoarea funcționare: | ||
| Line 877: | Line 885: | ||
| - dacă s-a primit același cuvânt cu cel trimis anterior, înseamnă că termenul nu a fost corect, astfel încât trebuie format un cuvânt cu același prefix ca anterior, acesta fiind afișat în câmpul text ''wordEdiTtext''; | - dacă s-a primit același cuvânt cu cel trimis anterior, înseamnă că termenul nu a fost corect, astfel încât trebuie format un cuvânt cu același prefix ca anterior, acesta fiind afișat în câmpul text ''wordEdiTtext''; | ||
| - altfel, se afișează un mesaj de eroare. | - altfel, se afișează un mesaj de eroare. | ||
| + | |||
| + | Informațiile cu privire la șirurile de caractere care au fost trimise, respectiv primite, vor fi jurnalizate în câmpurile text ''serverHistoryTextView'' și ''clientHistoryTextView''. | ||
| **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@pdsd2015:~/Laborator06$ git add * | + | student@eim2016:~/Laborator06$ git add * |
| - | student@pdsd2015:~/Laborator06$ git commit -m "implemented taks for laboratory 06" | + | student@eim2016:~/Laborator06$ git commit -m "implemented taks for laboratory 06" |
| - | student@pdsd2015:~/Laborator06$ git push Laborator02_perfectstudent master | + | student@eim2016:~/Laborator06$ git push Laborator02_perfectstudent master |
| </code> | </code> | ||
