|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Oct 2004
Città: Messina
Messaggi: 684
|
Problemi con java.net
Ciao ragazzi, ho nuovamente problemi...
NetBeans 5.5 sputa fuori queste eccezioni, in un applicativo che usa java.net.* java.net.BindException: Permission denied at java.net.PlainSocketImpl.socketBind(Native Method) at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:359) at java.net.ServerSocket.bind(ServerSocket.java:319) at java.net.ServerSocket.<init>(ServerSocket.java:185) at java.net.ServerSocket.<init>(ServerSocket.java:97) at simserver.Interf1.<init>(Interf1.java:30) at simserver.Main.main(Main.java:27) Ora non so se è un fatto di porte non nattate del router dannazione... Il codice è questo: Codice:
/*
* Main.java
*
* Created on 9 febbraio 2007, 9.50
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package simserver;
import java.io.*;
/**
*
* @author ale
*/
public class Main {
/** Creates a new instance of Main */
public Main() {
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws IOException {
// TODO code application logic here
Interf1 interf=new Interf1(900);
interf.setVisible(true);
}
}
Codice:
/*
* Mserver.java
*
* Created on 9 febbraio 2007, 9.50
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package simserver;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
/**
*
* @author ale
*/
public class Mserver extends JFrame implements Runnable {
protected Socket client;
private JLabel notifica;
Thread thr;
/** Creates a new instance of Mserver */
public Mserver(Socket skt) {
super(skt.getInetAddress().toString());
this.setVisible(true);
notifica=new JLabel("Arrivato nuovo client da "+ skt.getInetAddress());
client=skt;
}
public void init() {
thr=new Thread(this);
getContentPane().add(notifica);
pack();
}
public void start() {
thr.start();
}
public void run() {
try {
InputStream i=client.getInputStream();
OutputStream o=client.getOutputStream();
PrintStream p=new PrintStream(o);
p.println("Benvenuti");
p.println("Digitare HELP per lista servizi");
int x;
ByteArrayOutputStream command=new ByteArrayOutputStream();
String helpcommand=new String("HELP");
String quitcommand=new String("QUIT");
while((x=i.read())>-1) {
o.write(x);
if(x==13) {
p.println();
if(helpcommand.equalsIgnoreCase(command.toString()))
p.println("Il solo servizio disponibile è l'help");
else if(quitcommand.equalsIgnoreCase(command.toString())) {
p.println("BYE.");
try {
Thread.sleep(1000);
}
finally {
break;
}
}
else
p.println("Comando non disponibile.");
command.reset();
}
else if(x!=10)
command.write(x);
}
}
catch(IOException e) {
e.printStackTrace();
}
finally {
notifica.setText("Connessione chiusa con " + client.getInetAddress());
try {
client.close();
}
catch(IOException e) {
e.printStackTrace();
}
}
}
}
Codice:
/*
* Interf1.java
*
* Created on 9 febbraio 2007, 10.42
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
package simserver;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
/**
*
* @author ale
*/
public class Interf1 extends JFrame {
private JLabel message;
private JLabel attesa;
/** Creates a new instance of Interf1 */
public Interf1(int port) {
message=new JLabel("Server in partenza sulla porta " + port);
getContentPane().add(message);
pack();
try {
ServerSocket svr=new ServerSocket(port);
message.setText("Server partito sulla porta " + svr.getLocalPort());
Socket client;
attesa=new JLabel("");
getContentPane().add(attesa);
while(true) {
client=svr.accept();
attesa.setText("Richiesta di connessione da " + client.getInetAddress());
(new Mserver(client)).start();
}
}
catch(IOException e) {
e.printStackTrace();
}
}
}
Provato con altre porte diverse da 900 ma mi da lo stesso risultato, sia con windows che con Linux |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Oct 2004
Città: Messina
Messaggi: 684
|
Sono stato 3 ore a cercare un problema che non c'era...
Non vedevo il messaggio di lancio del server perchè la setVisible del JFrame era impostata esternamente, grazie a quel demente del mio prof che mi ha insegnato cosi' Ovviamente alla seconda esecuzione del server mi diceva che la porta era già in uso... -_-' |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Se mi permetti di dirlo, il tuo non è un buon "design". Già solo la classe Interf1 non va affatto bene. Hai usato metodi che agiscono sulla interfaccia utente e metodi che lavorano con i socket allegramente insieme e per di più nel costruttore della classe ... il tutto eseguito dallo stesso thread.
Quando viene costruita l'istanza di Interf1, non sei nel thread di Swing, quindi non dovresti interagire con l'interfaccia utente. Idem nella classe Mserver.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
|
|
|
|
#4 | |
|
Senior Member
Iscritto dal: Oct 2004
Città: Messina
Messaggi: 684
|
Quote:
Io estendo JFrame appositamente per interagire con Swing... Intendi che dovrei avere una classe che gestisca separatamente i socket e istanziarla dentro quelle che mi servono ? Lo dici per un motivo squisitamente estetico oppure pensi che puo' portare a problemi di sincronizzazione coi thread ? fino a estendere la classe JFrame e implementare la Runnable contemporaneamente mi pare che non ci siano problemi vero ? Le amenità iniziano utilizzando socket liberi dentro la suddetta e li hai ragionissima... dimmi la tua... vabbè si e poi in effetti tutto il codice messo dentro il costruttore è una blasfemia (lo so) Ultima modifica di Lakaj : 09-02-2007 alle 20:03. |
|
|
|
|
|
|
#5 | |
|
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
Se devi interagire con l'interfaccia utente Swing (es. fare un setText su un componente o cose del genere), devi farlo nel contesto del suo thread, cioè devi essere all'interno di quello che si chiama event-dispatch thread. Agire sull'interfaccia utente direttamente da un altro thread potrebbe causare problemi di concorrenza! Leggi <qui>.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|
|
|
|
|
|
#6 | |
|
Senior Member
Iscritto dal: Oct 2004
Città: Messina
Messaggi: 684
|
Quote:
Codice:
// Execute all GUI code on the event dispatch thread, even initialization:
EventQueue.invokeLater(new Runnable() { public void run() {
// Create frame with title "Hello, World!"
JFrame f = new JFrame("Hello, World!");
etc.
etc.
Eppure sul Mokabook ha quella filosofiaIo purtroppo sono vittima della mia università, della mia città e della mia regione, che è forse troppo vicina all'Africa... Ultima modifica di Lakaj : 09-02-2007 alle 23:25. |
|
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Oct 2004
Città: Messina
Messaggi: 684
|
Quindi, in teoria, un codice del genere, anche se ordinato e preciso, potrebbe portare a problemi di concorrenza ?
Codice:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class JTextFieldExample extends JFrame {
private JTextField textField;
private JLabel label;
public JTextFieldExample() {
super(“JTextField”);
setSize(200, 80);
getContentPane().setLayout(new BorderLayout());
textField = new JTextField();
label = new JLabel();
getContentPane().add(BorderLayout.NORTH, textField);
textField.addActionListener(new EnterTextListener());
getContentPane().add(BorderLayout.SOUTH, label);
setVisible(true);
}
class EnterTextListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
label.setText(“Testo inserito: “ + textField.getText());
textField.setText(“”);
}
}
public static void main(String argv[]) {
JTextFieldExample jtf = new JTextFieldExample();
}
}
|
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Oct 2004
Città: Messina
Messaggi: 684
|
O meglio, per evitare problemi di concorrenza, dovrei creare un'istanza di JTextFieldExample all'interno di
Codice:
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new JTextFieldExample().setVisible(true);
}
});
A quanto ho capito la invokeLater rappresenta un ambiente sicuro in cui esiste certezza che un dato componente A non possa essere disturbato diciamo 'simultaneamente'(anche se in un contesto mono-processore la parola simult. è errata) da 2 diversi blocchi di codice... Ultima modifica di Lakaj : 10-02-2007 alle 11:50. |
|
|
|
|
|
#9 | |||
|
Senior Member
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
|
Quote:
Prima di quella chiamata, il frame non è ancora visibile e non è cioè "realized". Quindi, sebbene tutta la inizializzazione la fai nel contesto del "main" thread e non nel event-dispatch thread, non dovrebbero esserci problemi di concorrenza. Per questo caso specifico, si intende. Quote:
Quote:
Quindi, dentro quel Runnable, le operazioni che fai sull'interfaccia utente sono intrinsecamente sicure. Dopotutto il e.d.t. fa solo una cosa per volta ... o sta aggiornando l'interfaccia utente, o sta dispacciando un evento o sta eseguendo un tuo Runnable. La differenza tra i due metodi è solo il fatto del sincrono/asincrono. E per invokeAndWait c'è da notare che non deve essere usato se si è già nel e.d.t. (altrimenti blocchi tutto!).
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%) |
|||
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 20:56.











ha quella filosofia








