PDA

View Full Version : [Java] Problema socket solo su Windows


spidey
17-07-2008, 09:30
Salve a tutti. Ho un problema che mi sta affliggendo.
Il codice seguente mi da errore solo su Windows mentre su Linux funziona alla perfezione.
Nel ciclo while del client il programma lancia un eccezzione perchè è come se trovasse occupata la socket a cui tenta di connettersi, anche se ho provveduto a chiuderla alla fine del ciclo precedente, infatti in linux tali socket risultano aperte.

Spero di essere stato chiaro ad esporre il mio problema.
Ringrazio in anticipo chiunque cerchi d' essermi di aiuto :muro:

CODICE SERVER
import java.net.*;
import java.io.*;

public class Server extends Thread{

public int port ;

public static final int DEFAULT_MAX_CLIENT_NUMBER=10;

Server(int port){
this.port=port;

}


public boolean controllaId(String id){

BufferedReader read= null;
BufferedWriter writer = null;

try{

read = new BufferedReader(new InputStreamReader(
new FileInputStream("C:/Documents and Settings/Lib/Desktop/Prenotazioni.txt")));

}catch(FileNotFoundException exc){
System.err.println("File non trovato!");
}

String s;
//String stringaId=String.valueOf(id);
try{
while((s = read.readLine()) != null){
if(s.compareTo(id)==0);
return true;
}
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("C:/Documents and Settings/Lib/Desktop/Prenotazioni.txt")));
writer.write(id+"\n");
writer.flush();
return false;
}catch(IOException e){
System.err.println("errore");
return false;
}


}


public void run(){



try{


ServerSocket socket = new ServerSocket(port,DEFAULT_MAX_CLIENT_NUMBER);



while (true){

System.out.println("Server in ascolto sul porto "+ port);
Socket socket_from_client= socket.accept();
System.out.println("Accettata connessione dal client " + socket_from_client.getPort() );


BufferedReader reader = new BufferedReader(new InputStreamReader(socket_from_client.getInputStream()));

System.out.println("\nReading...");

String richiesta = reader.readLine()+"\n";
System.out.println("Ricevuta richiesta tipo :" + richiesta);


BufferedWriter writer= new BufferedWriter(new OutputStreamWriter(socket_from_client.getOutputStream()));
writer.write("OK"+"\n");
writer.flush();

String ID = reader.readLine()+ "\n";
System.out.println("ricevuta richiesta dal client ID: "+ID);

if(controllaId(ID))
writer.write("PRENOTAZIONE_AGGIORNATA"+"\n");

else
writer.write("PRENOTAZIONE_EFFETTUATA"+ "\n");


System.out.println("Mi rimetto in attesa ;) ");

writer.flush();

socket_from_client.close();



}

}catch(IOException e){
System.err.println("Qualcosa è andato male!!!");
e.printStackTrace();


}}




public static void main(String args[]){

Server server= new Server(40001);

server.start();

}

}


CODICE CLIENT

import java.io.*;
import java.net.*;
import java.net.InetAddress;

public class Client extends Thread {

private int localport,serverport;

private String ServerAddress;

public static int nome = 0;
public int ID;

public String richiesta = ("RICHIESTA_PRENOTAZIONE");

Client(int lp, int sp, String sa){

this.ID= this.nome++;

this.localport = lp;
this.serverport = sp;

this.ServerAddress = sa;

}


public void run(){
try{
int i=0;


Socket socket = null;


while(i < 2){


socket = new Socket(InetAddress.getByName(this.ServerAddress), this.serverport,InetAddress.getLocalHost(),this.localport) ;
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));


writer.write(richiesta+"\n");

System.out.println(Thread.currentThread() + " ho scritto " + richiesta);

writer.flush();

System.out.println(Thread.currentThread() + "Sto attendendo risposta ");
String risposta= reader.readLine()+ "\n";
System.out.println(Thread.currentThread() + " ha ricevuto "+risposta);

writer.write(ID+"\n");
System.out.println("ho scritto " + ID);
writer.flush();

risposta= reader.readLine();
System.out.println(Thread.currentThread()+ " Esito prenotazione: "+ risposta+"\n");

i++;
writer.close();
reader.close();
socket.close();
}

}
catch(IOException e){
System.err.println("Exception : errore di I/O durante la comunicazione con il server");
e.printStackTrace();
}
}




public static void main(String[] args){

int port=50000;
for (int i=0; i < 10; i++){

(new Client(port, 40001, "127.0.0.1")).start();
port++;
}





}

}



OUTPUT DEL SERVER SOTTO WINDOWS

Server in ascolto sul porto 40001
Accettata connessione dal client 50009

Reading...
Ricevuta richiesta tipo :RICHIESTA_PRENOTAZIONE

ricevuta richiesta dal client ID: 9

Mi rimetto in attesa ;)
Server in ascolto sul porto 40001
Accettata connessione dal client 50002

Reading...
Ricevuta richiesta tipo :RICHIESTA_PRENOTAZIONE

ricevuta richiesta dal client ID: 2

Mi rimetto in attesa ;)
Server in ascolto sul porto 40001
Accettata connessione dal client 50004

Reading...
Ricevuta richiesta tipo :RICHIESTA_PRENOTAZIONE

ricevuta richiesta dal client ID: 4

Mi rimetto in attesa ;)
Server in ascolto sul porto 40001
Accettata connessione dal client 50005

Reading...
Ricevuta richiesta tipo :RICHIESTA_PRENOTAZIONE

ricevuta richiesta dal client ID: 5

Mi rimetto in attesa ;)
Server in ascolto sul porto 40001
Accettata connessione dal client 50007

Reading...
Ricevuta richiesta tipo :RICHIESTA_PRENOTAZIONE

ricevuta richiesta dal client ID: 7

Mi rimetto in attesa ;)
Server in ascolto sul porto 40001
Accettata connessione dal client 50001

Reading...
Ricevuta richiesta tipo :RICHIESTA_PRENOTAZIONE

ricevuta richiesta dal client ID: 1

Mi rimetto in attesa ;)
Server in ascolto sul porto 40001
Accettata connessione dal client 50008

Reading...
Ricevuta richiesta tipo :RICHIESTA_PRENOTAZIONE

ricevuta richiesta dal client ID: 8

Mi rimetto in attesa ;)
Server in ascolto sul porto 40001
Accettata connessione dal client 50006

Reading...
Ricevuta richiesta tipo :RICHIESTA_PRENOTAZIONE

ricevuta richiesta dal client ID: 6

Mi rimetto in attesa ;)
Server in ascolto sul porto 40001
Accettata connessione dal client 50003

Reading...
Ricevuta richiesta tipo :RICHIESTA_PRENOTAZIONE

ricevuta richiesta dal client ID: 3

Mi rimetto in attesa ;)
Server in ascolto sul porto 40001
Accettata connessione dal client 50000

Reading...
Ricevuta richiesta tipo :RICHIESTA_PRENOTAZIONE

ricevuta richiesta dal client ID: 0

Mi rimetto in attesa ;)
Server in ascolto sul porto 40001


OUTPUT CLIENT SOTTO WINDOWS
Thread[Thread-3,5,main] ho scritto RICHIESTA_PRENOTAZIONE
Thread[Thread-3,5,main]Sto attendendo risposta
Thread[Thread-2,5,main] ho scritto RICHIESTA_PRENOTAZIONE
Thread[Thread-2,5,main]Sto attendendo risposta
Thread[Thread-4,5,main] ho scritto RICHIESTA_PRENOTAZIONE
Thread[Thread-4,5,main]Sto attendendo risposta
Thread[Thread-5,5,main] ho scritto RICHIESTA_PRENOTAZIONE
Thread[Thread-5,5,main]Sto attendendo risposta
Thread[Thread-7,5,main] ho scritto RICHIESTA_PRENOTAZIONE
Thread[Thread-7,5,main]Sto attendendo risposta
Thread[Thread-1,5,main] ho scritto RICHIESTA_PRENOTAZIONE
Thread[Thread-1,5,main]Sto attendendo risposta
Thread[Thread-8,5,main] ho scritto RICHIESTA_PRENOTAZIONE
Thread[Thread-8,5,main]Sto attendendo risposta
Thread[Thread-9,5,main] ho scritto RICHIESTA_PRENOTAZIONE
Thread[Thread-9,5,main]Sto attendendo risposta
Thread[Thread-9,5,main] ha ricevuto OK

ho scritto 9
Thread[Thread-6,5,main] ho scritto RICHIESTA_PRENOTAZIONE
Thread[Thread-6,5,main]Sto attendendo risposta
Thread[Thread-0,5,main] ho scritto RICHIESTA_PRENOTAZIONE
Thread[Thread-0,5,main]Sto attendendo risposta
Thread[Thread-9,5,main] Esito prenotazione: PRENOTAZIONE_AGGIORNATA

Thread[Thread-2,5,main] ha ricevuto OK

ho scritto 2
Thread[Thread-2,5,main] Esito prenotazione: PRENOTAZIONE_AGGIORNATA

Thread[Thread-4,5,main] ha ricevuto OK

ho scritto 4
Thread[Thread-4,5,main] Esito prenotazione: PRENOTAZIONE_AGGIORNATA

Thread[Thread-5,5,main] ha ricevuto OK

ho scritto 5
Thread[Thread-5,5,main] Esito prenotazione: PRENOTAZIONE_AGGIORNATA

Thread[Thread-7,5,main] ha ricevuto OK

ho scritto 7
Thread[Thread-7,5,main] Esito prenotazione: PRENOTAZIONE_AGGIORNATA

Thread[Thread-1,5,main] ha ricevuto OK

ho scritto 1
Thread[Thread-1,5,main] Esito prenotazione: PRENOTAZIONE_AGGIORNATA

Thread[Thread-8,5,main] ha ricevuto OK

ho scritto 8
Thread[Thread-8,5,main] Esito prenotazione: PRENOTAZIONE_AGGIORNATA

Thread[Thread-6,5,main] ha ricevuto OK

ho scritto 6
Thread[Thread-6,5,main] Esito prenotazione: PRENOTAZIONE_AGGIORNATA

Thread[Thread-3,5,main] ha ricevuto OK

ho scritto 3
Thread[Thread-3,5,main] Esito prenotazione: PRENOTAZIONE_AGGIORNATA

Thread[Thread-0,5,main] ha ricevuto OK

ho scritto 0
Thread[Thread-0,5,main] Esito prenotazione: PRENOTAZIONE_AGGIORNATA

Exception : errore di I/O durante la comunicazione con il server
java.net.BindException: Address already in use: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at Client.run(Client.java:40)
Exception : errore di I/O durante la comunicazione con il server
java.net.BindException: Address already in use: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at Client.run(Client.java:40)
Exception : errore di I/O durante la comunicazione con il server
java.net.BindException: Address already in use: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at Client.run(Client.java:40)
Exception : errore di I/O durante la comunicazione con il server
java.net.BindException: Address already in use: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at Client.run(Client.java:40)
Exception : errore di I/O durante la comunicazione con il server
java.net.BindException: Address already in use: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at Client.run(Client.java:40)
Exception : errore di I/O durante la comunicazione con il server
java.net.BindException: Address already in use: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at Client.run(Client.java:40)
Exception : errore di I/O durante la comunicazione con il server
Exception : errore di I/O durante la comunicazione con il server
java.net.BindException: Address already in use: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at Client.run(Client.java:40)
Exception : errore di I/O durante la comunicazione con il server
java.net.BindException: Address already in use: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at Client.run(Client.java:40)
Exception : errore di I/O durante la comunicazione con il server
java.net.BindException: Address already in use: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at Client.run(Client.java:40)
java.net.BindException: Address already in use: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at Client.run(Client.java:40)

ilsensine
17-07-2008, 10:03
Cambia qualcosa se nel client imposti localport a 0?

spidey
17-07-2008, 10:06
No, da la stessa eccezzione :(

spidey
17-07-2008, 10:21
Si adesso funziona!!!! Prima non avevo tolto il port++ dal main del client. Ora funziona!!!!
Grazie mille!!!
Sapresti spiegarmi il perchè di ciò?:confused:

ilsensine
17-07-2008, 10:26
Perché a forza di incrementare port, sei giundo a una porta già occupata da qualcuno. Solo per caso non hai osservato il problema su linux.

Tranne casi particolari, la porta del client va messa su 0 e il suo indirizzo di bind su 0.0.0.0, in modo da lasciare al sistema operativo la scelta.

spidey
17-07-2008, 10:32
Ok, chiarissimo. Ti ringrazio :D
Avrei anche un altra domanda ;)
potresti dare un occhiata alla funzione che mi aggiorna il file? io volevo creare un file avente su ogni riga tutti gli id ricevuti dal server, solo che se apro il file vedo che esso contiene caratteri strani ed inoltre la prenotazione risulta sempre aggiornata anche se cancello tali caratteri..

ilsensine
17-07-2008, 10:41
Credo perché stai scrivendo un "int" e non la sua rappresentazione stringa. Però non conosco il java, potrei sbagliarmi; dovrebbe commentare qualcun altro.

spidey
17-07-2008, 10:44
Si anche io ci avevo pensato, solo che nn trovo il modo di convertirlo dato che lo leggo con un readline() che restituisce una string.
Cmq ti ringrazio ;)

banryu79
17-07-2008, 12:00
Si anche io ci avevo pensato, solo che nn trovo il modo di convertirlo dato che lo leggo con un readline() che restituisce una string.
Cmq ti ringrazio ;)
Puoi convertirlo con Integer.parseInt(yourString).

spidey
17-07-2008, 13:15
Il problema era nel fatto che l' if della funzione controllaId innanzitutto aveva un punto e virgola assurdo che nn so come ce l' ho messo :° e poi la condizione nn era mai verificata poichè la s letta con readline() nn prendeva un carattere di \n che ho provveduto ad appendere stesso all' interno del while.
Adesso funziona tutto alla perfezione.
Ringrazio tutti per le risposte ;)