PDA

Visualizza la versione completa : [JAVA] Scambio dati tra client e server personalizzati tramite socket


Dylan_Web
06-10-2004, 10:00
Salve a tutti.
E' un p di tempo che sto lavorando con il pacchetto java.net.
Sto creando un'applicazione server-client.

Il mio server in ascolto perenne in attesa che client ci si connettano.
Una volta che il client richiede una connessione si avvia una classe thread che lo gestisce.

Il tutto gestito tramite una form
Tasto listen -> ciclo infinito di attesa su richiesta di connessione, e avvia di un thread a richiesta di connessione.
Tasto ricevi -> riceve dati dai client e visualizzarli nel jtextbox assocciato
Tasto invia -> invia dati ai client




Il mio problema il seguente
Una volta ricevuto dati dal client, non riesco a visualizzarli sulla textbox.Questo perch la classe Jframe si trova in attesa di altri client, ma ovviamente riesco a visualizzarli sulla shell, (questo per dire che comunque i dati vengono ricevuti) (non esiste una listen, non blocking come in c :bh: )

P.S.
I tasti ricevi e invia non sono ancora implementati.
I dati vengono ricevuti nel thread.

Fox82
06-10-2004, 10:44
Prova a postare un po' di codice...

LeleFT
06-10-2004, 11:18
La soluzione al tuo problema consiste nel costruire una classe separata per il Server e lasciare la finestra come applicazione indipendente. Il server, a questo punto, sara' un Thread che gira all-interno della finestra. In questo modo la finestra non viene bloccata dal Server. A grandi linee la struttura e' simile a questa:


public class Finestra extends JFrame {
private Server server;
...
public Finestra() {\
... // inizializzazioni varie
server = new Server(this); // gli passo un puntatore alla finestra per le comunicazioni
}

// metodo chiamato dal pulsante per l'ascolto dei client
private void avviaIlServer() {
server.start();
}

public void scriviSullaTextArea(String testo) {
textArea.setText(testo);
}
}

public class Server extends Thread {
private Finestra f;
public Server(Finestra f) {
this.f = f;
}
...
private void ricevutoMessaggio(Messaggio msg) {
String testo = msg.getTexto(); // prendo il testo del messaggio o simili
f.scriviSullaTextArea(testo);
}
}

Se il server e' in un oggetto Thread separato (una classe a se stante) la finestra non si blocca, mentre il server e' in attesa di connessioni e/o messaggi. Il thread, dal canto suo, comunica con la finestra attraverso il puntatore e puo' spedire i messaggi da visualizzare in modo indipendente.


Ciao. :ciauz:

Dylan_Web
06-10-2004, 15:18
Ciao Ragazzi, non ci posso credere !!!!
Ce l'ho fatta!

Ho creato un Server che si mette in ascolto indefinito di client e riceve da essi in qualsiasi momento!


Grazie mille per i vostri aiuti.

Se volete vi post il codice. :ciauz:


P.S.
Vi vorrei porre un'altro problema...
Il seguente:
Con il mio codice riesco ad inviare e ricevere dati dai client, ma solo sotto forma di stringa.
Vorrei se possibile inviare e ricevere una struct... tutti mi hanno detto che devo serializzare e deserializzare.Ma con rispetto parlando non so nemmeno cosa significhi.

Qualcuno per caso ha gi provato a fare questa cosa.Mi potreste indirizzare.Grazie Mille

Fox82
06-10-2004, 18:33
Serializzare significa scomporre l'oggetto (che una struttura complessa) in un flusso di byte, inviarlo lungo un canale di I/O per ricomporlo poi dall'altra parte.

Per una spiegazione dettagliata ti rimando a questo (http://www.javaolympus.com/thinking/TIJ314.htm#Heading15545) link, tratto da Thinking in Java di Bruce Eckel

LeleFT
06-10-2004, 19:21
In sostanza, si tratta semplicemente di scrivere una classe che rappresenta la tua struttura da inviare/ricevere e far implementare l'interfaccia Serializable alla classe:


import java.io.Serializable;

public class MiaStruttura implements Serializable {
...
}

Ciao. :ciauz:

_sys/sid
06-10-2004, 19:44
@Dylan_Web: Posta il codice...

Dylan_Web
07-10-2004, 09:39
Ciao Ragazzi, eccovi il codice.Divertivi
Ci sono 3 classi interne
Listen
Ricezione
Invia

[*CODE]
//Importo i package
import java.net.*;
import java.io.*;
import java.io.Reader;

public class Server_Form extends javax.swing.JFrame {

// contatore dei client attivi //
int count = -1;
// massimo 50 Client //
int MAXCLIENT = 50;
// Array di Socket per i client //
Socket socket[] = new Socket[MAXCLIENT];
// Socket di ascolto //
ServerSocket serverSocket;


/** Creates new form JFrame */
public Server_Form() {
try {
serverSocket = new ServerSocket(7777);
} catch (IOException e)
{

System.out.println("IOException: " + e);
System.out.println("\nErrore verificatosi sull'apertura del socket sulla porta!\n");
}
initComponents();
}

/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
private void initComponents() {
jDesktopPane1 = new javax.swing.JDesktopPane();
jTextPane1 = new javax.swing.JTextPane();
jTextPane2 = new javax.swing.JTextPane();
jButton3 = new javax.swing.JButton();
jButton1 = new javax.swing.JButton();
jLabel2 = new javax.swing.JLabel();
jLabel1 = new javax.swing.JLabel();

addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent evt) {
exitForm(evt);
}
});

jTextPane1.setEditable(false);
jTextPane1.setBounds(60, 110, 260, 110);
jDesktopPane1.add(jTextPane1, javax.swing.JLayeredPane.DEFAULT_LAYER);

jTextPane2.setBounds(200, 230, 140, 30);
jDesktopPane1.add(jTextPane2, javax.swing.JLayeredPane.DEFAULT_LAYER);

jButton3.setText("Click me for Listen");
jButton3.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
jButton3MouseClicked(evt);
}
});

jButton3.setBounds(100, 280, 160, 60);
jDesktopPane1.add(jButton3, javax.swing.JLayeredPane.DEFAULT_LAYER);

jButton1.setText("Dati da inviare");
jButton1.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
jButton1MouseClicked(evt);
}
});

jButton1.setBounds(20, 230, 160, 30);
jDesktopPane1.add(jButton1, javax.swing.JLayeredPane.DEFAULT_LAYER);

jLabel2.setFont(new java.awt.Font("Times New Roman", 3, 24));
jLabel2.setText("DATI RICEVUTI");
jLabel2.setBounds(70, 60, 210, 40);
jDesktopPane1.add(jLabel2, javax.swing.JLayeredPane.DEFAULT_LAYER);

jLabel1.setText("Server non in ascolto");
jLabel1.setBounds(50, 20, 270, 50);
jDesktopPane1.add(jLabel1, javax.swing.JLayeredPane.DEFAULT_LAYER);

getContentPane().add(jDesktopPane1, java.awt.BorderLayout.CENTER);

pack();
}

private void jButton1MouseClicked(java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
Invia invia = new Invia(this);
invia.start();
}

private void jButton3MouseClicked(java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
Listen listen = new Listen(this , serverSocket);
listen.start();
}

/** Exit the Application */
private void exitForm(java.awt.event.WindowEvent evt) {
System.exit(0);
}

/**
* @param args the command line arguments
*/
public static void main(String args[]) {
Server_Form MyForm = new Server_Form();
MyForm.setSize(400 , 400);
MyForm.show();
//MyForm.jButton1.setEnabled(false);
}

// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton3;
private javax.swing.JDesktopPane jDesktopPane1;
public javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
public javax.swing.JTextPane jTextPane1;
public javax.swing.JTextPane jTextPane2;
// End of variables declaration

}

class Listen extends Thread {

private ServerSocket server_socket;

private Server_Form frame;

/**
* Creates a new instance of Listen
*/
public Listen(Server_Form serverframe, ServerSocket socketascolto) {
this.server_socket = socketascolto;
this.frame = serverframe;
}

public void run() {
// Ciclo infinito in attesa di client , non ci dimentichiamo che l'accept bloccante //
while(true) {
try {
frame.jLabel1.setText("SERVER IN ASCOLTO SULLA PORTA 7777");
System.out.println("In attesa di chiamate dai Client... ");
frame.count++;
frame.socket[frame.count] = server_socket.accept();

System.out.println("Ho ricevuto una chiamata di apertura da:\n" + frame.socket[frame.count]);
Ricezione ricezione = new Ricezione(frame.socket[frame.count] , frame);
ricezione.start();


} catch (IOException e) {
System.out.println("IOException: " + e);}
}
}

}

class Ricezione extends Thread {

private Socket Connesso;

private Server_Form frame;

/**
* Creates a new instance of Ricezione
*/
public Ricezione(Socket Connesso_ric, Server_Form frame_ric) {
this.Connesso = Connesso_ric;
this.frame = frame_ric;
}

public void run() {
// Ciclo infinito in attesa di client , non ci dimentichiamo che l'accept bloccante //
String old;
try {
DataInputStream is = new DataInputStream(Connesso.getInputStream());

InputStreamReader(Connesso.getInputStream()));

while(true) {

System.out.println("STO RICEVENDO DATI");
String userInput = is.readLine();
System.out.println("Ricevuto " + userInput);
if (userInput == null || userInput.equals("QUIT"))
break;
if (frame.jTextPane1.getText() != null) {
old = frame.jTextPane1.getText() + "\n" + userInput;}
else {
old = userInput;}
frame.jTextPane1.setText(old);

System.out.println("Il Client ha scritto: " + userInput);
}
//d.close();
is.close();
}
catch (IOException e) {
System.out.println("IOException: " + e);
}

}

}

class Invia extends Thread {

private Server_Form frame;

/**
* Creates a new instance of Invia
*/
public Invia(Server_Form frame_ric) {
this.frame = frame_ric;
}

public void run() {
String Dati_inviare;
try {
for(int i=0 ; i < frame.count ; i++) {
DataOutputStream os = new DataOutputStream(frame.socket[i].getOutputStream());
Dati_inviare = frame.jTextPane2.getText();
System.out.println("DATI da inviare" + Dati_inviare);
os.writeBytes(Dati_inviare);
System.out.println("DATI INVIATI");
//os.close();
}
} catch (IOException e) {
System.out.println("IOException: " + e);
}

}

}
[*/CODE]

Un p lungo Vero?Ma altrettanto interessante... :unz: :unz: :unz:

Alex'87
21-03-2006, 21:53
Originariamente inviato da Dylan_Web
Con il mio codice riesco ad inviare e ricevere dati dai client, ma solo sotto forma di stringa.
Vorrei se possibile inviare e ricevere una struct... tutti mi hanno detto che devo serializzare e deserializzare.Ma con rispetto parlando non so nemmeno cosa significhi.





x inviare:

ObjectOutputStream objOut = new ObjectOutputStream(socket.getOutputStream())

objOut.writeObject(oggetto da inviare (che implementa Serializable));

x ricevere:

ObjectInputStream objIn = new ObjectInputStream(socket.getInpuStream());

Object obj = objIn.readObject();

alka
22-03-2006, 10:25
Per favore, non inserire risposte in discussioni concluse da tempo.

Loading