View Full Version : [JAVA] E' possibile istanziare Enne Server Socket?
Salve a tutti
Come da titolo , è possibile istanziare in maniera dinamica (solo a run time quindi) Enne Server Socket, ognua con porte diverse , sullo stesso pc?
Abbiamo provato ad istanziarne tre , con lo stesso nome ma con porte diverse...
funziona solo l'ultima..
Grazie ciao :)
Posta un esempio
Premetto che ciò che voglio realizzare siano Enne serversocket (enne definito in input dall'utente).
Allora , vado a memoria non ho il codice sottomano:
Pippo = new ServerSocket(1000);
Pippo = new ServerSocket(2000);
Pippo = new ServerSocket(3000);
Lo so che , a rigor di logica , con istruzioni del genere l'unica utilizzabile sarà sempre e solo la terza (3000) , solo che leggendo in giro qua e là avevo visto che ciò che veniva modificato , in nuove istanziazioni , era l'indirizzo o locazione di memoria della variabile...
Ho fatto un gran confusione lo ammetto :stordita:
Leggendo e chiedendo in giro ho visto che qualcosa di utile al mio scopo potrebbe venire dalle liste , più precisamente da questo
http://www.dia.uniroma3.it/~cabibbo/fiji/sorgenti/fiji-docs/fiji/util/LinkedList.html
Dovrebbe andar bene , che ne pensate?
Ogni singola serverSocket sarà poi identificata grazie al metodo getlocalport , dato che ogni Socket controlla una e una sola porta...
Se fai in quel modo solo la terza rimane attiva, le altre due vengono distrutte dal garbage collector.
Scusa creati un array di servesocket, così risolvi
Scusa creati un array di servesocket, così risolvi
Il fatto è che dovrei istanziarle dinamicamente , quindi credo che una struttura dati array non vada bene...
Per questo propendevo verso una Lista
Grazie ad entrambi comunque :)
banryu79
30-01-2009, 11:06
Il fatto è che dovrei istanziarle dinamicamente , quindi credo che una struttura dati array non vada bene...
Per questo propendevo verso una Lista
Grazie ad entrambi comunque :)
Usa un ArrayList<ServerSocket> ;)
@EDIT:
o meglio, leggendo questo:
Ogni singola serverSocket sarà poi identificata grazie al metodo getlocalport , dato che ogni Socket controlla una e una sola porta...
potresti creare un HashMap usando come chiave (key) la local port (un int) e come valore (value) un ServerSocket:
// inizializzazione hashmap: nessun elemento
HashMap<Integer, ServerSocket> socketMap = new HashMap<Integer, ServerSocket>;
// aggiungo un elemento
ServerSocket ss = new bla bla...
...
Integer socketID = new Integer(ss.getLocalPort());
socketMap.put(socketID , ss));
// recupero un ServerSocket usando la local port come chiave
ServerSocket aSocket = socketMap.get(socketID);
...
// controllo se nella hashMap c'è un ServerSocket mappato con una chiave specifica
Interger specificPort = new Integer(1000);
boolean keyIsPresent = socketMap.containsKey(specificPort );
...
// recupero tutte le chiavi nella hashMap (tutte le localPort mappate)
Set<Integer> allPorts = socketMap.keySet();
...
// recupero tutti i valori nella hashMap (tutti i ServerSocket mappati)
ArrayList<ServerSocket> allSocket = socketMap.values();
...
Usa un ArrayList<ServerSocket> ;) in questo caso meglio LinkedList<ServerSocket>
banryu79
30-01-2009, 11:27
in questo caso meglio LinkedList<ServerSocket>
Ciao fero86, ho letto adesso, nel frattempo stavo editanto il post.
A questo punto per me meglio un hashmap.
Ciao fero86, ho letto adesso, nel frattempo stavo editanto il post.
A questo punto per me meglio un hashmap.
Ciao e grazie per i consigli :)
Posso chiederti perchè preferisci un hash map ad un linkedlist?
Saluti
P.s: Grazie a tutti quelli che mi hanno risposto
EDIT: per hashmap ti riferisci a questo?
http://www.nocturnal.it/njl/it/hashmap.html
banryu79
30-01-2009, 12:14
EDIT: per hashmap ti riferisci a questo?
http://www.nocturnal.it/njl/it/hashmap.html
Javadoc: HashMap (http://java.sun.com/javase/6/docs/api/java/util/HashMap.html).
Fa parte del Collections Framework (http://java.sun.com/javase/6/docs/technotes/guides/collections/index.html) incluso nel JDK
Posso chiederti perchè preferisci un hash map ad un linkedlist?
Come ho detto prima, perchè ho considerato questo requisito da te espresso:
Ogni singola serverSocket sarà poi identificata grazie al metodo getlocalport...
e quindi se identifichi un serverSocket con la sua localPort ha senso mappare la coppia <local port value, server socket> per sfruttare il fatto che l'inserimento e il recupero di valori da una hasmap tramite i suoi metodi put e get ha tempo costante, tutto qui.
Mi sembra di capire che la logica della collezione di ServerSocket che vorresti non è quella di identificare uno specifico ServerSocket in base all'ordine con cui è stato inseriro nella collezione, ma in base alla local port a cui fa riferimento; in modo quindi indipendente dalla sua posizione nella collezione.
Javadoc: HashMap (http://java.sun.com/javase/6/docs/api/java/util/HashMap.html).
Fa parte del Collections Framework (http://java.sun.com/javase/6/docs/technotes/guides/collections/index.html) incluso nel JDK
Come ho detto prima, perchè ho considerato questo requisito da te espresso:
e quindi se identifichi un serverSocket con la sua localPort ha senso mappare la coppia <local port value, server socket> per sfruttare il fatto che l'inserimento e il recupero di valori da una hasmap tramite i suoi metodi put e get ha tempo costante, tutto qui.
Mi sembra di capire che la logica della collezione di ServerSocket che vorresti non è quella di identificare uno specifico ServerSocket in base all'ordine con cui è stato inseriro nella collezione, ma in base alla local port a cui fa riferimento; in modo quindi indipendente dalla sua posizione nella collezione.
Esattamente.
Non mi interessa la posizione che assumerà la Server Socket , ma esclusivamente il valore della porta , nullaltro...
Altra domanda:
Il mio amico , con cui sto facendo questo progetto , mi ha detto che non è possibile (testato da lui) istanziare ServerSocket dandogli in input una variabile intera , esempio:
Int pippo = 1000;
ServerSocket ss = new ServerSocket (pippo);
Da errore in compilazione , il valore deve essere statico , costante... :confused:
Grazie ciao :)
non mi pare a vedere la documentazione.. quell'int con la i maiuscola l'hai messo solo qui o anche nel tuo codice?
banryu79
30-01-2009, 15:09
C'è un errore:
int pippo = 1000;
ServerSocket ss = new ServerSocket (pippo);
Scusate ho scritto male
In realtà la int sarebbe ovviamente scritta con la i minuscola , il problema è un altro(ho sbagliato a scrivere)...
int pippo;
...
... (verrà definitito in queste righe di codice , che sia da input o in maniera random...)
...
ServerSocket ss = new ServerSocket (pippo);
Da documentazione , dite voi , dovrebbe funzionare giusto?
Saluti
Immagino tu stia usando questo:
http://java.sun.com/javase/6/docs/api/java/net/ServerSocket.html
In particolare a te interessa il secondo costruttore. Come chiede un ingresso un intero, quindi non dovrebbero esserci problemi ;)
Per quanto riguarda la struttura dati, la HashMap è nettamente superiore in questo caso rispetto a Linked e ArrayList, in quanto sia inserimento che ricerca sono O(1) (vuol dire tempo costante, cioè grossomodo indipendente dalla quantità di Socket, in parole spicciole). Anche se dubito arriverai a istanziarne un numero tale da poter discriminare in prestazioni le varie soluzioni :)
Immagino tu stia usando questo:
http://java.sun.com/javase/6/docs/api/java/net/ServerSocket.html
In particolare a te interessa il secondo costruttore. Come chiede un ingresso un intero, quindi non dovrebbero esserci problemi ;)
Esattamente , sto utilizzando il secondo costruttore.
Adesso proveremo poi vi faremo sapere , se ho problemi posto qui , grazie ancora a tutti :)
Allora...rieccomi di nuovo
Tramite l'utilizzo della HashMap le varie ServerSocket sono state istanziate , perfettamente direi...
E' sorto però un altro problema: dato che i miei Server devono stare sempre in ascolto su queste porte , ho creato un metodo Listen che , tramite un ciclo infinito (while(true)) , provvede allo scopo.
Dove sta il problema? Che solamente la prima ServerSocket su cui verrà applicato il metodo Listen resterà in ascolto , le altre dovranno aspettare la terminazione di quest'ultima...
Come fare quindi per istanziare più ServerSocket che stiano in ascolto , contemporaneamente , su più porte , tante quante i Server?
P.s: Il trattamento della connessione Server/Client è gestito già tramite thread , in modo che più CLient possano connettersi al Server.
Questo però non sembra aver risolto il problema...
banryu79
04-02-2009, 18:16
Puoi postare gli spezzoni di codice relativi a questo:
E' sorto però un altro problema: dato che i miei Server devono stare sempre in ascolto su queste porte , ho creato un metodo Listen che , tramite un ciclo infinito (while(true)) , provvede allo scopo.
Dove sta il problema? Che solamente la prima ServerSocket su cui verrà applicato il metodo Listen resterà in ascolto , le altre dovranno aspettare la terminazione di quest'ultima...
e a questo:
P.s: Il trattamento della connessione Server/Client è gestito già tramite thread , in modo che più CLient possano connettersi al Server.
Questo però non sembra aver risolto il problema...
Sarebbero d'aiuto per capire esattamente quale è il problema.
Leggi qui: http://www.hwupgrade.it/forum/showthread.php?t=1356151
Metodo Listen() (è un pò lunghetto....)
private void Listen() throws IOException
{
//-- Dichiarazione delle variabili
Socket Sock = null; //Nuova socket creata dalla ServerSocket dopo aver accettato la richiesta di un Client
InetAddress IPSocket = null; //Indirizzo IP del Client
String IPSock = null; //Indirizzo IP del Client convertito in stringa
System.out.println("Creazione del Server riuscita");
//- Informazioni aggiuntive sul Server
System.out.println("-Informazioni sul Server");
System.out.println(SerSocket);
System.out.println("");
//-- Ciclo infinito che continua ad accettare le richieste dei Client
System.out.println("Server in ascolto sulla porta " + porta + " e in attesa di connessione...");
System.out.println("");
while(true)
{
try
{
Sock = SerSocket.accept(); //Si crea una nuova socket accettando la richiesta di un Client
System.out.println("Connessione al Client "+ Sock.getInetAddress() + " riuscita");
}
catch(IOException e3)
{
System.out.println("ERRORE! Impossibile stabilire la connessione con il Client: " + e3);
}
//- Informazioni aggiuntive sul Client
System.out.println("-Informazioni sul Client");
System.out.println(Sock);
IPSocket = Sock.getInetAddress(); //Acquisire l'indirizzo IP del Client
IPSock = String.valueOf(IPSocket); //Conversione di un InetAddress in una stringa
//-- Richiamo del Firewall per controllo del Client
Firewall Wall = new Firewall(Sock); //Dichiarazione di un nuovo oggetto Firewall
System.out.println("");
System.out.println("Verifica del Client in corso...");
//-- Controllo sui valori aggiornati dal Firewall
if (Wall.verClient(IPSock) == true)
{
System.out.println("IP proibito: il Client è presente nella lista nera!");
System.out.println("Terminazione della connessione in corso...");
try
{
Sock.close();
System.out.println("");
System.out.println("Comunicazione con il Client terminata");
System.out.println("----------");
System.out.println("");
}
catch(IOException e4)
{
System.out.println("");
System.out.println("ERRORE! Impossibile chiudere la connessione con il client: " + e4);
System.out.println("----------");
System.out.println("");
}
}
else
{
System.out.println("IP valido...");
new ServerFunction(Sock,Wall,IPSock).run(); //Dichiarazione di un nuovo oggetto ServerFunction con invocazione del metodo run
}
}
}
}
Metodo Create (istanzia la HashMap che prende i valori delle porte da un file di testo)
private void Create()
{
//-- Dichiarazione delle variabili
FileReader fr = null; //Variabile che permette di leggere il file contenente le porte da istanziare
Scanner scan = null; //Variabile che legge ogni riga presente nella file delle porte
String portTxt = null; //Stringa contenente una porta da aprire
HashMap listPorte = null; //Lista virtuale contenente
int portList; //Porta da aprire
//-- Apertura e lettura del file contenente le porte da aprire
try
{
fr = new FileReader("Porte.txt"); //Legge la il file contenente le porte da aprire
}
catch(FileNotFoundException e)
{
System.out.println("ERRORE! File non trovato: " + e);
}
scan = new Scanner(fr); //Permette di leggere il contenuto del file riga per riga
listPorte = new HashMap(); //Creazione di un nuovo oggetto HashMap
//-- Ciclo che continua a leggere il file finchè sono presenti delle righe al suo interno
while(scan.hasNext())
{
portTxt = scan.nextLine(); //Si legge la riga successiva
portList = Integer.parseInt(portTxt); //Conversione della stringa in intero
try
{
SerSocket = new ServerSocket(portList); //Creazione della ServerSocket che resta in ascolto sulla porta prestabilita
}
catch(IOException e1)
{
System.out.println("ERRORE! " + e1);
}
listPorte.put(portList, SerSocket); //Aggiunge un elemento nella HashMap
System.out.println(listPorte.get(portList)); //Visualizzazione a video del contenuto della HashMap
}
}
banryu79
04-02-2009, 18:44
@Dyd87: fatti un favore, leggiti il pdf che trovi al link che ti ha indicato cionci ;)
Per quanto riguarda il tuo codice stasera non riesco a vederlo perchè sto staccando adesso dall'ufficio, forse domani: nel frattempo tu leggiti quel tutorial :)
@Dyd87: fatti un favore, leggiti il pdf che trovi al link che ti ha indicato cionci ;)
Per quanto riguarda il tuo codice stasera non riesco a vederlo perchè sto staccando adesso dall'ufficio, forse domani: nel frattempo tu leggiti quel tutorial :)
Ok grazie :)
Intanto se qualcuno ha dei commenti da fare sul codice , ben venga ;)
Hai letto quella cosa sui socket non bloccanti ? Può fare al caso tuo ;)
Hai letto quella cosa sui socket non bloccanti ? Può fare al caso tuo ;)
Ho incominciato a dargli un'occhiata...
Praticamente con delle Socket BLOCCANTI (il mio caso in pratica) la Cpu da spazio ad una socket finchè questa non ha ricevuto tot numero byte/informazioni..
Con quelle NON bloccanti , ciò non avviene...sbaglio?
P.s.: Scusate l'eventuale premura che ho messo nel porre le domande , solo che questo è un progetto d'esame , che sto facendo con un altro.
Oramai dati gli sviluppi e i problemi non sarà cosa di questa sessione , però ci terrei a capirne il più possibile, quindi grazie di cuore a tutti :)
La parte interessante era che puoi controllare N ServerSocket con un solo thread in attesa che ci sia un client pronto per la accept. In questo modo la accept diventa non bloccante.
La parte interessante era che puoi controllare N ServerSocket con un solo thread in attesa che ci sia un client pronto per la accept. In questo modo la accept diventa non bloccante.
A tuo parere vedendo come ho impostato il codice è fattibile modificarlo in maniera semplice?
In maniera semplice direi proprio di no.
In maniera semplice direi proprio di no.
Grazie della precisazione :D
Leggi qui: http://en.allexperts.com/q/Java-1046/2008/3/Socket-Programming-Threading-Listen-1.htm
In alternativa appunto bisogna usare un ServerSocketChannel per ogni porta, settare configureBlocking a false. A questo punto con la classe Selector è possibile controllare tutti i socket contemporaneamente con un solo thread.
Una volta individuato tramite Selector un evento su uno dei ServerSocketChannel, fai la accept ed hai il tuo Socket da passare ai thread che gestiscono la richiesta.
Rieccomi qui :D
Dopo molto tempo siamo ritornati sul problema in questione , trovando molto utile ed interessante il PDF da voi linkato.
Il problema che si presenta è un altro ora: avremmo pensato di non utilizzare il metodo del selettore per istanziare più Server Socket , pensi il Multithreading (un thread per serversocket).
Dato che si pensava di realizzare una sorta di firewall però la discussione è caduta sulla gestione delle porte: come fare?
Ovvero , quale delle due metodologie (Multithreading o selettore) utilizzare per gestire al meglio il controllo delle doors €(:D) ?
Avevamo pensato al nostro firewall (semplicissimo , anche troppo) come un programma che controllasse tutte le eventuali connessioni dall'esterno.
Per fare ciò dovevamo monitorare tutte le porte , azione scatenante il secondo problema , o meglio , dubbio: quante porte bisogna controllare?
Teoricamente le porte "accessibili" sono 65536 , il che porta a due strade:
- Metodo Multithreading: 65536 thread , uno per porta/server socket (:eek: )
- Metodo Selettore : Un selettore , un thread , 65536 server socket (:eek: )
Ripeto che il firewall che vogliamo programmare è di una semplicità assurda , deve solo verificare la presenza o meno di eventuali connessioni provenienti dall'esterno (no dall'interno per il momento).
Sapreste darci un consiglio?
Grazie mille
Saluti :)
Non sono - tra l'altro - un esperto di firewall ma non credo che operino ad un livello così alto. Immagino che anzichè star lì attaccati ad ogni possibile porta si siedano più in basso, dove il concetto di porta ancora non c'è, in modo tale da poter intercettare tutto l'intercettabile.
Per quanto riguarda il multithreading ricorda che ti servono due livelli: uno è la pluralità di thread che accettano le connessioni - un Thread per ogni ServerSocket - e uno è la pluralità di Thread che gestiscono la connessione - un Thread per ogni Socket accettato.
Puoi anche gestire la cosa con un mix blocking-non blocking, ad esempio dedicando un Thread a ogni ServerSocket il quale userà poi un selettore non bloccante.
A conti fatti dipende tutto dal carico di lavoro e dalle caratteristiche della macchina. E' il classico problema della scalabilità. Io in astratto propenderei per una configurazione che generi un selettore per ogni Thread fisicamente supportato dalla macchina ma è una euristica perchè in mezzo ci finisce il resto del lavoro del sistema operativo.
Grazie mille per i consigli.
In merito a questa parte:
Non sono - tra l'altro - un esperto di firewall ma non credo che operino ad un livello così alto. Immagino che anzichè star lì attaccati ad ogni possibile porta si siedano più in basso, dove il concetto di porta ancora non c'è, in modo tale da poter intercettare tutto l'intercettabile.
Hai detto di non essere esperto ma secondo te , su cosa si dovrebbe lavorare al posto delle porte?
Saluti :)
Grazie mille per i consigli.
In merito a questa parte:
Hai detto di non essere esperto ma secondo te , su cosa si dovrebbe lavorare al posto delle porte?
Saluti :)
Neanche io sono esperto di firewall, tuttavia per quello che so dovresti lavorare sui pacchetti a livello di rete ;).
Tanto per la cronaca, le socket sono l'interfaccia tra livello applicativo e livello di trasporto, sotto il livello di trasporto (TCP e UDP solitamente nelle reti IP) trovi il livello di rete (IP).
Ora non so se Java mette a disposizione le RawSocket per lavorare a livello di rete per poter analizzare il contenuto dei pacchetti ed estrapolare le informazioni che ti servono, cmq tanto per farti un'idea della struttura dei pacchetti TCP e UDP:
http://en.wikipedia.org/wiki/Transmission_Control_Protocol#TCP_segment_structure
http://en.wikipedia.org/wiki/User_Datagram_Protocol#Packet_structure
E i pacchetti di rete IP (supponiamo versione 4) che li incapsulano:
http://en.wikipedia.org/wiki/IPv4#Packet_structure
Lavorando a livello di rete in teoria dovresti poter vedere qualsiasi pacchetto che arriva al tuo pc, poiché poi è compito del livello di trasporto consegnare tale pacchetto a tale applicazione (che è in listening su una data porta).
Tuttavia facendo un programma applicativo che analizza il traffico a livello di rete, non credo tu possa bloccare le altre applicazioni eventualmente in ascolto su una data porta.
Nel senso, se hai 2 programmi A e B e:
A è in ascolto sulla porta 1234
B si occupa di leggere i pacchetti a livello di rete
Nel momento in cui B legge un pacchetto a livello di rete che incapsula ad esempio un segmento destinato alla porta 1234, nulla impedisce ad A di riceverlo.
Spero di essere stato chiaro.
Per andare più in basso devi scendere credo al livello di sistema operativo, delle sue api ed eventualmente di drivers.
Cmq già fare un'analizzatore di pacchetto è una bella cosa :D. Tipo Wireshark :sofico:
[Aggiunta: rispondo a Dyd87]
Guarda quando uno parla di una tecnologia che non conosce sa sempre tutto di magia per cui te la racconto per come mi appare.
Le porte sono tante ma il filo è uno solo quindi qualcosa che non va ci dev'essere.
Precisamente - termine un po' forte - tra il filo e le porte deve esserci uno strato che divide i pacchetti in entrata tra le diverse porte.
Che il firewall non operi su ogni singola porta astrattamente apribile mi sembra una conseguenza dell'impossibilità di eccedere un certo numero di connessioni attive. Se volesse operare sulle porte infatti dovrebbe aprirle tutte e poi intercettare tutte le richieste di apertura rinviandole a sè stesso: non potrebbe limitarsi ad una scansione ciclica di ogni porta aperta perchè tra un passaggio e l'altro qualcuno potrebbe aprire una porta non attualmente "visionata" e il firewall sarebbe un colabrodowall.
Dal che deriva il mio sospetto che operi più in basso - prima delle porte, appunto.
Da questo a dire come si arrivi a quel punto della rete ce ne corre: per me l'os potrebbe benissimo sgozzare un capretto e danzare nudo intorno al fuoco sputando rhum sugli astanti. Ma immagino che da qualche parte ci sia della documentazione che spiega come arrivare fin laggiù.
Grazie ad entrambi :)
Quindi mi consigliate praticamente di operare a livello di rete utilizzando le Rawsocket o , eventualmente , il loro corrispettivo in Java?
Per i firewall a scopo "educativo" si opera esattamente aprendo 65536 porte TCP ;)
In verità non sono firewall, è solo un'esercitazione.
vedi, non si finisce mai di imparare.
Per i firewall a scopo "educativo" si opera esattamente aprendo 65536 porte TCP ;)
In verità non sono firewall, è solo un'esercitazione.
Scusa potresti spiegarti meglio?
C'è qualcosa che non mi torna...
Grazie mille :)
Cosa c'è da spiegare ? Per realizzare un "firewall" (anche se è difficile chiamarlo firewall) a scopo didattico va bene l'approccio che avevi pensato all'inizio. Ne ho viste tante di richieste simili in questi anni e tutti lo hanno realizzato così.
Non ci sono altri metodi nell'immediato. Per realizzare qualcosa a livello più basso non si può certo lavorare in Java, o comunque non solo in Java.
Cosa c'è da spiegare ? Per realizzare un "firewall" (anche se è difficile chiamarlo firewall) a scopo didattico va bene l'approccio che avevi pensato all'inizio. Ne ho viste tante di richieste simili in questi anni e tutti lo hanno realizzato così.
Non ci sono altri metodi nell'immediato. Per realizzare qualcosa a livello non si può certo lavorare in Java, o comunque non solo in Java.
Capito , grazie mille.
Perdona l'insistenza nel fare domande ma volevo esser sicuro di ciò che leggevo, per evitare fraintendimenti.
Grazie ancora a tutti :)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.