Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 14
  1. #1

    Client/Server comportamento socket anomalo

    Salve gente,
    ho provato a dare uno sguardo in giro ma credo che nessuno abbia riscontrato un problema simile, quindi ho aperto un nuovo topic e vado ad enunciarvi la situazione :
    sto realizzando una grande applicazione client/server come progetto di laurea, e dopo innumerevoli righe di codice mi trovo di fronte ad una situazione paradossale su di una socket. Scrivo due righe di codice, per comprenderci :
    In questa specifica funzione il client invia un file da salvare sul server, e per farlo utilizza una socket nuova, diversa da quella che utilizza per la connessione;
    sul server ho queste poche righe di codice per realizzare il tutto :
    codice:
    Socket s=new Socket(cli.getInetAddress(),8888);
    BufferedReader i = new BufferedReader(new InputStreamReader(s.getInputStream()));
    File f=new File("C:\\ServerInfo\\"+i.readLine());
    FunzioniServer.storeOnServer(s, f);
    la variabile cli contiene la socket attuale mediante cui sono connessi client e server

    mentre sul client ho :
    codice:
    ServerSocket ss=new ServerSocket(8888);
    Socket s = ss.accept();
    ss.close();
    PrintStream out = new PrintStream(s.getOutputStream(), true);
    out.println(chooser.getSelectedFile().getName());
    Funzioni.uploadFile(s, chooser.getSelectedFile());
    Il problema è questo : mentre il client si ferma sulla accept ad aspettare la connessione, il server apre tranquillamente la socket (nonostante io abbia verificato che l'indirizzo verso cui va la socket è lo stesso della macchina cliente che attende la connessione) e si blocca alla penultima riga che ho postato, in attesa della readLine sul Reader.
    La situazione è alquanto paradossale già posta così, lo diventa ancor di più se aggiungo che, avendo provato ad impostare la serverSocket nel server e la socket nel client il tutto funziona bene..
    Spero di essere stato abbastanza chiaro, e spero che qualcuno di voi sappia spiegarmi cosa accade

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Fossi in te aggiungere un flush() dopo la println() altrimenti il dato non arriverà mai dall'altra parte se non è sufficientemente lungo da riempire il buffer.

    codice:
    PrintStream out = new PrintStream(s.getOutputStream(), true);
    out.println(chooser.getSelectedFile().getName());
    out.flush();
    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    Ciao, innanzitutto ti ringrazio per la risposta!
    Poi volevo farti notare che probabilmente non hai letto bene il problema , infatti io avevo scritto che il client si blocca molto prima, ovvero sulla accept della socket.. E dunque si crea questo strano paradosso per cui sul server è stata avviata una connessione socket verso quel determinato ip e su quella porta, mentre sul client la connessione non risulta e si rimane in attesa.
    Infine credo che un flush sia inutile, in quanto il costruttore della PrintStream che ho usato prende anche un boolean che è il parametro dell'autoFlush

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Effettivamente mi erano sfuggiti sia il true per l'autoFlush, sia il fatto che nel client si ferma alla accept(). E' un problema che mi era già capitato e non ricordo di aver trovato una soluzione (credo che sia un problema a livello più basso: hai un client che diventa server per la macchina che gli sta facendo da server: non voglio dire cavolate, ma questo complica parecchio le cose a livello di routing).

    Una domanda che richiede una risposta, credo, scontata: la porta delle due connessioni è diversa vero? Cioè... la prima connessione non avviene sulla 8888, mi auguro.

    Nel frattempo mi documento e, appena ho un attimo, faccio delle prove.

    PS: Qual è la necessità di aprire un canale separato fra client e server?

    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  5. #5
    Cercherò di rispondere alle tue domande nella maniera più completa possibile:
    In primis, ovviamente le porte sono diverse, altrimenti avrei avuto un errore all'apertura della ServerSocket perchè la porta era già occupata
    Poi, utilizzare diverse connessioni mi serve per consentire diverse operazioni tra le entità, utilizzando quindi la connessione stabilita all'inizio come canale di segnalazione e le varie nuove connessioni per il flusso dati(sopratutto trasferimenti).
    Però il problema risiede nel fatto che fino ad ora io ho implementato diversi servizi, tutti che sfruttano questo stesso principio e che consentono alle entità di fare alternativamente da client e da server, e questo è il primo errore.
    Come avevo già scritto nel mio primo post, se inverto le funzioni e quindi apro la ServerSocket sul server facendovi connettere il client, il tutto funziona bene, ma devo lavorare un po' di sincronizzazione perchè potenzialmente diverse entità connesse al server potrebbero richiedere la stessa operazione e, in questo caso, un solo client riuscirebbe a connettersi mentre gli altri si ritroveranno con un errore perchè la porta sul server si trova già aperta!

  6. #6
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    non ho chiaro il motivo per cui devi fare agire anche il client da server, nella comunicazione ad un certo punto hai

    1. client richiede invio file
    2. server accetta file --> usa connessione che già ha messo su
    3. server rifiuta --> do nothing
    4. chiusura connessione

    penso che in questo modo sia più semplice e ti risolvi problemi diversi (es porte disponibili sul server, comunicazione porta al client, apertura connessione, eventuali firewall sul client ecc ecc)
    RTFM Read That F*** Manual!!!

  7. #7
    Il tuo ragionamento è corretto, però se avvio il trasferimento di un file particolarmente grande, il client è inibito per una certa quantità di tempo, potenzialmente lunga..

  8. #8
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    e ci sta, ma gestisci tu la quantità che scrivi sul buffer, quindi in questo caso gestisci tu la comunicazione (idle e altre cose).
    L'alternativa è fare una comunicazione server-server con problemi che crescono esponenzialmente (io te ne ho presentato solo alcuni), raddoppiando di fatto la comunicazione, visto che la prima serve da "handshake" particolare
    RTFM Read That F*** Manual!!!

  9. #9
    Sono pienamente daccordo con te, e credo che sarà quella una delle strade che seguirò nel caso in cui non riesca a trovare una soluzione diversa... Anche perchè buona parte dei problemi che hai elencato li avevo previsti e risolti... Però mi rimane strano il motivo di tutto ciò
    PS... Tutto quello che ho elencato nel primo post non si verifica se client e server girano sulla stessa macchina, e la comunicazione avviene senza intoppi

  10. #10
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    e i firewall?
    RTFM Read That F*** Manual!!!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.