Sunteți pe pagina 1din 10

Aplicaţii client – server ( II ) 103

Lucrare de laborator nr. 7


Aplicaţii client - server ( II )

1. Scopul lucrării
În această lucrare se continuă studiul aplicaţiilor client - server
bazate pe socketuri. În plus, se exemplifică şi realizarea unor aplicaţii
client în modul grafic.

2. Breviar teoretic

În aplicaţia client se creează obiectul socket apoi, pe baza lui,


se creează cele două obiecte care gestionează comunicaţia de date cu
serverul şi anume: obiectul BufferedReader folosit pentru a citi datele
de la server şi obiectul PrintWriter folosit pentru a scrie date către
server.
În aplicaţia server se instanţiază un obiect ServerSocket în care
se specifică portul de la server pe care se desfăşoară comunicaţia, apoi
se intră într-o buclă de repetare infinită în care se aşteaptă conectarea
unui client. Această aşteptare se face cu metoda accept() din clasa
ServerSocket. Metoda returnează un obiect Socket (ce împacheteaza
informaţia de IP şi port) pentru clientul conectat. Pentru clientul
acceptat se creează un fir de execuţie căruia i se transmite ca
parametru obiectul Socket prin care se va comunica cu acest client, şi
apoi folosind metoda start() se startează firul de execuţie.
Firul de execuţie poate fi implementat prin extinderea clasei
Thread sau prin implementarea interfeţei Runnable .
Un exemplu de implementare prin extinderea clasei Thread
este următorul:
Fir f=new Fir( … );//se specifica parametrii necesari
f.start();
Şi clasa Fir are urmatoarea structură:
class Fir extends Thread
{
//varibilele de instanta ale clasei Fir:
104 Aplicaţii client - server ( II )

......
//constructorul clasei Fir:
.....
public void run()
{//corpul metodei run():
.....
}
//alte metode in clasa Fir:
.....
}//end clasa Fir
Cea de a doua metodă de creare a unui fir de execuţie, prin
implementarea interfeţei Runnable, este cea folosită în problemele
rezolvate şi va fi exemplificată în soluţiile problemelor.

3. Probleme rezolvate
Problema 1
Să se scrie o aplicaţie client server în care în aplicaţia client se
repetă următoarea secvenţă de operaţii:
-se citeşte de la tastatură un şir de caractere.
-daca şirul este şirul vid, se iese din aplicaţia client.
-şirul se transmite la server, care va cripta şirul recepţionat cu
algoritmul de criptare Mansfield şi apoi transmite rezultatul clientului.
-în aplicaţia client se afişează rezultatul trimis de către server (şirul
criptat).
În criptare nu vom face diferenţă între literele mici şi cele mari.
Algoritmul de criptare Mansfield este un algoritm de criptare
prin substituţie în care se criptează doar literele, restul caracterelor se
lasă neschimbate ( litera Q se va cripta la fel ca si litera P ). Fiecare
literă se substituie cu două vocale, astfel:
Avem 25 de litere distincte din alfabetul englez, deoarece P şi Q se
criptează la fel. Cele 25 de litere le asezăm într-un tabel (matrice) de 5
linii şi 5 coloane. Acestea corespund celor 5 vocale. Pentru o literă
oarecare mai întâi aflăm linia şi coloana din tabel, pe care se află. Să
presupunem că se află în linia 1 şi coloana 4 (litera J).Începem
numerotarea liniilor şi a coloanelor de la 0. Această literă se va
substitui cu a doua vocală şi cu a cincia vocală din alfabet, deci cu EU.

Listingul aplicatie client


import java.net.*;import java.io.*;import java.util.*;
Aplicaţii client – server ( II ) 105

public class ClientCriptareMansfield


{
public static void main(String args[]) throws IOException
{
Socket cs=null;
BufferedReader bfr=null;
PrintWriter pw=null;
try{
cs=new Socket("127.0.0.1",5000);//localhost
InputStreamReader isr=
new InputStreamReader(cs.getInputStream());
bfr=new BufferedReader(isr);
pw=new PrintWriter(cs.getOutputStream());
System.out.println("S-a setat reteaua");
//pentru citire de la tastatura:
BufferedReader kbd=
new BufferedReader(new InputStreamReader(System.in));
for(;;){
System.out.print("sir = ");
String s=kbd.readLine();
if(s.equals("")){pw.println("");pw.flush();break;}//se deconecteaza
//acest client, si instiinteaza si serverul pentru a-i opri firul de
// executie
pw.println(s); pw.flush();
String textIn=bfr.readLine();
if(textIn==null)break;
System.out.println(textIn);
}//for;;
}catch(IOException e){
e.printStackTrace();
}
}//main
}//class

Listingul aplicatiei server


import java.io.*;import java.net.*;import java.util.*;
public class ServerCriptareMansfield
{
public static void main(String args[])
{
106 Aplicaţii client - server ( II )

System.out.println("Am pornit server...");


try{
ServerSocket ss=new ServerSocket(5000);
for(;;){
Socket cs=ss.accept();
Thread firPtClient=new Thread(new MotorFirClient(cs));
firPtClient.start();
System.out.println("Avem o conectare!");
}//for;;
}catch(Exception e){
e.printStackTrace();
}
}//main()
}//class ServerCriptareMansfield

class MotorFirClient implements Runnable


{
private Socket cs;
private BufferedReader bfr;
private PrintWriter pw;
//constructorul clasei:
public MotorFirClient(Socket clientsock)
{
try{
cs=clientsock;
pw=new PrintWriter(cs.getOutputStream());
InputStreamReader isr=
new InputStreamReader(cs.getInputStream());
bfr=new BufferedReader(isr);
}catch(Exception e){
e.printStackTrace();
}
}

public void run()


{
String textIn;
try{
for(;;){
textIn=bfr.readLine();
Aplicaţii client – server ( II ) 107

if(textIn==null)break;
if(textIn.equals(""))break
;//s-a deconectat clientul ( a tastat ENTER);
String raspuns=criptareMansfield(textIn);
//trimite la client raspunsul:
pw.println(raspuns);
pw.flush();
}//for;;
}catch(Exception e){
e.printStackTrace();
}
}//run

private String criptareMansfield(String s)


{
/* matricea 5x5 cu literele alfabetului (fara litera Q):
ABCDE
FGHIJ
KLMNO
PRSTU
VWXYZ
*/
char vocale[]={'A','E','I','O','U'};
String s1=s.toUpperCase();
String rezultat="";
for(int i=0;i<s1.length();i++){
char ch=s1.charAt(i);
//Este litera caracterul ch ?
if(Character.isUpperCase(ch))
{
if(ch=='Q')ch='P';// Caracterele Q si P se cripteaza la fel
//Calculam cele doua vocale cu care se substituie caracterul ch.
//Calculam numarul de ordine in alfabetul normal de 26 de
// caractere pt. caracterul ch:
int pozAlfabetNormal=(int)ch-(int)'A';
//Calculam numarul de ordine in alfabetul modificat, de 25 de
//caractere pt. caracterul ch:
int poz;
if((int)ch>=(int)'R')poz=pozAlfabetNormal-1;
else poz=pozAlfabetNormal;
108 Aplicaţii client - server ( II )

//Calculam linia si coloana din matrice 5x5 ce contine alfabetul


//modificat dde 25 de litere, in care apare caracterul ch:
int linie=poz/5;
int coloana=poz%5;
//Substituim caracterul ch cu cele doua vocale:
rezultat=rezultat+vocale[linie]+vocale[coloana];
}
else rezultat=rezultat+ch;//ch nu este litera. Se lasa neschimbat.
}
return rezultat;
}//criptareMansfield()
}//classMotorFirClient

Problema 2
Aceeaşi aplicaţie client server ca în problema 1, dar acum
clientul este realizat în modul grafic. Şirul de criptat se va introduce în
fereastra grafică, intr-o componentă JTextField. Rezultatul venit de la
server se va afişa de asemenea într-o componentă JTextField.
Fereastra grafică este ilustrată în figura următoare:

Listingul aplicaţie client


import java.net.*;import java.io.*;
import javax.swing.*;import java.awt.*;import java.awt.event.*;
Aplicaţii client – server ( II ) 109

public class ClientGraficCriptareMansfield


{
public static void main(String args[])
{
Socket cs=null;
BufferedReader bfr=null;
PrintWriter pw=null;
try{
cs=new Socket("127.0.0.1",5000) ;
InputStreamReader isr=
new InputStreamReader(cs.getInputStream());
bfr=new BufferedReader(isr);
pw=new PrintWriter(cs.getOutputStream());
}catch(UnknownHostException e){
System.out.println("eroare la conectare: "+e);
System.exit(1);
}catch(IOException e){
System.out.println("eroare la conectare: "+e);
System.exit(1);
}
//instantiem fereastra grafica:
Fereastra f=new Fereastra(bfr,pw);
f.setVisible(true);
}//main
}//class ClientGraficCriptareMansfield
class Fereastra extends JFrame
{
private JButton jbCalcul, jbExit;
private JTextField jtf1, jtf2;
private BufferedReader bfr;
private PrintWriter pw;
public Fereastra(BufferedReader bfr, PrintWriter pw )
{
this.bfr=bfr;
this.pw=pw;
this.setTitle("Client criptare");
this.setSize(600, 400);
JLabel jl1=new JLabel("text de criptat:");
jtf1=new JTextField(40);
JPanel jp1=new JPanel( );
110 Aplicaţii client - server ( II )

jp1.add(jl1); jp1.add(jtf1);
JLabel jl2=new JLabel("text criptat:");
jtf2=new JTextField(40);
JPanel jp2=new JPanel( );
jp2.add(jl2); jp2.add(jtf2);
AscultaButoane ab=new AscultaButoane( );
jbCalcul=new JButton("Trimite la sever");
jbCalcul.addActionListener(ab);
jbExit=new JButton("Exit");
jbExit.addActionListener(ab);
JPanel jp3=new JPanel( );
jp3.add(jbCalcul); jp3.add(jbExit);
JPanel jp=new JPanel( );
jp.setLayout(new GridLayout(3,1));
jp.add(jp1); jp.add(jp2); jp.add(jp3);
Container cFinal=this.getContentPane( );
cFinal.add(jp,"South");
}// end constructor
// clasa interioara:
class AscultaButoane implements ActionListener
{
public void actionPerformed(ActionEvent ev)
{
Object sursa=ev.getSource();
if(sursa==jbExit)System.exit(0);
else if (sursa==jbCalcul){
String s1=jtf1.getText( );
if(s1.equals("")){
//se deconecteaza acest client, si instiinteaza
// si serverul pentru a-i opri firul de executie
pw.println("");
pw.flush();
System.exit(0);
}
//sirul s1 este diferit de sirul vid:
String raspuns="";
try{
//trimiteDateCatreServer:
pw.println(s1);
//goleste fluxul:
Aplicaţii client – server ( II ) 111

pw.flush();
raspuns=bfr.readLine();
if(raspuns==null)return;
}catch(IOException e){
e.printStackTrace();
System.exit(1);
}
jtf2.setText(""+raspuns);
jtf1.requestFocus();
}//else
}//actionPerformed()
}
}
Listingul aplicaţie server
Aplicaţia server este în modul text, deci codul aplicaţiei este
identic cu codul aplicaţiei server din problema 1.

3. Probleme propuse

Problema 1
Să se scrie o aplicaţie client server în care în aplicaţia client se
repetă următoarea secvenţă de operaţii:
-se citeşte de la tastatură un şir de caractere.
-daca şirul este şirul vid, se iese din aplicaţia client.
-şirul se transmite la server, care va cripta şirul recepţionat cu
algoritmul de criptare Caesar şi apoi transmite rezultatul clientului.
-în aplicaţia client se afişează rezultatul trimis de către server (şirul
criptat).
Algoritmul de criptare Caesar este un algoritm de criptare prin
substituţie în care se criptează doar literele, restul caracterelor se lasă
neschimbate. Fiecare literă se substituie cu litera aflată la distanţă de
trei litere de ea, în alfabet. Astfel, litera a se substituie cu litera d, b cu
e, etc. Pentru ultimele trei litere din alfabet: x se substituie cu a, y cu b
şi z cu c.

Problema 2
Aceeaşi aplicaţie client server ca în problema 1, dar acum
clientul este realizat în modul grafic. Şirul de criptat se va introduce în
fereastra grafică, intr-o componentă JTextField. Rezultatul venit de la
server se va afişa de asemenea într-o componentă JTextField.
112 Aplicaţii client - server ( II )

Problema 3
În aplicaţia client se repetă următoarea secvenţă de operaţii:
-se citeşte un şir de la tastatură
-dacă şirul tastat este vid ( se apasă doar tasta ENTER ), se iese din
aplicaţia client.
-altfel, şirul se transmite severului.
Aplicaţia client se va realiza în modul text.
Serverul criptează şirul recepţionat cu algoritmul de criptare prin
transpoziţie cu matrice şi il transmite clientului.
-în aplicaţia client se afişează rezultatul trimis de către server (şirul
criptat).
Algoritmul de criptare prin transpoziţie cu matrice este
următorul:
Se copiază textul de criptat într-o matrice pătratică de
caractere, de dimensiune minimă. Astfel, dacă textul are 25 de
caractere, dimensiunea matricii pătrate este 5. Dacă textul are 28 de
caractere, dimensiunea matricii va fi 6. Copierea textului în matrice se
face parcurgând matricea pe linii. Dacă mai rămâne loc neocupat în
matrice, se completează matricea cu spaţii (blankuri) . Şirul criptat se
obţine prin parcurgerea matricii pe coloane.

Problema 4
Se va realiza o aplicaţie client server, în care clientul este în
modul grafic.
În aplicaţia client se repetă următoarea secvenţă de operaţii:
-se citeşte un şir de la tastatură
-dacă şirul tastat este vid ( se apasă doar tasta ENTER ), se iese din
aplicaţia client.
- se selectează algoritmul de criptare prin două butoane radio, prezente
în interfaţa grafică ( criptare prin metoda Caesar sau criptare prin
transpoziţie cu matrice ).
- şirul se transmite severului împreună cu specificaţia referitoare la
algoritmul de criptare ( Caesar sau transpoziţie cu matrice ).
Serverul criptează şirul recepţionat cu algoritmul de criptare
specificat şi apoi il transmite clientului.
-în aplicaţia client se afişează rezultatul trimis de către server (şirul
criptat).

S-ar putea să vă placă și