Visualizzazione dei risultati da 1 a 4 su 4
  1. #1
    Moderatore di PHP L'avatar di Alhazred
    Registrato dal
    Oct 2003
    Messaggi
    12,505

    Simulazione di client e server web che non comunicano correttamente

    Ho scritto due classi una che funge da server web e una che si comporta come un browser (ma stampa semplicemente il codice html come una stringa senza interpretarlo), ovviamente entrambe ben lontane da un vero server ed un vero browser, sto solo provando le comunicazioni HTTP via socket.

    Se avvio il server e provo a contattarlo con Firefox ottengo una risposta corretta, ovvero una semplicissima pagina html.
    Se nel codice del browser che ho scritto metto l'indirizzo di un qualsiasi sito online e lo avvio, ottengo correttamente il codice html della pagina.
    Da questo capisco che da sole le 2 classi funzionano.

    Il problema nasce se avvio la mia classe "server" e poi la classe "browser" in cui specifico l'indirizzo del mio server, in tal caso l'output che ottengo, invece del codice html, è la stringa presente nel codice del browser
    codice:
    GET / HTTP/1.1\r\n\r\n
    Entrambe le classi le ho sotto lo stesso progetto su Eclipse e da lì ne avvio prima una (il server) e poi l'altra (il browser).
    Ho anche provato a farle partire da riga di comando in 2 terminali diversi in Ubuntu, stessa storia.

    Per quale motivo tra di loro non funzionano?

    Qui il codice delle 2 classi, così potete vedere se c'è qualcosa che no va o se volete fare delle prove.

    Server
    codice:
    import java.net.*;
    import java.io.*;
    
    public class SimpleWebServer {
        public static void main(String[] args) throws IOException {
    
            ServerSocket serverSocket = null;
            try {
                serverSocket = new ServerSocket(4444);
            } catch (IOException e) {
                System.err.println("Could not listen on port: 4444.");
                System.exit(1);
            }
    
            Socket clientSocket = null;
            try {
                clientSocket = serverSocket.accept();
            } catch (IOException e) {
                System.err.println("Accept failed.");
                System.exit(1);
            }
    
            PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
            BufferedReader in = new BufferedReader(
    				new InputStreamReader(
    				clientSocket.getInputStream()));
            String inputLine;
            
            while ((inputLine = in.readLine()) != null)
    		{
            	System.out.println(inputLine);
            	if (inputLine.equals("Connection: keep-alive")) break;
            }
            
            String message = new String(args[0]);
            
            out.println("HTTP/1.1 200 ok\r\n");
            out.println("<html>");
            out.println("<head>");
            out.println("<title> index </title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<p><b>PIPPO</b></p>");
            out.println("</body>");
            out.println("</html>");
            
            out.close();
            in.close();
            clientSocket.close();
            serverSocket.close();
        }
    }


    Browser
    codice:
    import java.io.*;
    import java.net.*;
    
    public class SocketSimpleWebBrowser {
        public static void main(String[] args) throws IOException {
    
            Socket echoSocket = null;
            PrintWriter out = null;
            BufferedReader in = null;
            
            try {
                echoSocket = new Socket("localhost", 4444);
                out = new PrintWriter(echoSocket.getOutputStream(), true);
                in = new BufferedReader(
                	new InputStreamReader(
                    echoSocket.getInputStream()));
            } catch (UnknownHostException e) {
                System.err.println("Don't know about the host");
                System.exit(1);
            } catch (IOException e) {
                System.err.println("Couldn't get I/O for this connection.");
                System.exit(1);
            }
    
    		out.println("GET / HTTP/1.1\r\n\r\n");
    
    		String data;
    
    		while ((data = in.readLine()) != null)
    		{
    	    	System.out.println(data);
    		}
    	
    		out.close();
    		in.close();
    		echoSocket.close();
        }
    }
    Ultima modifica di Alhazred; 03-11-2013 a 00:48

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da Alhazred Visualizza il messaggio
    Il problema nasce se avvio la mia classe "server" e poi la classe "browser" in cui specifico l'indirizzo del mio server, in tal caso l'output che ottengo, invece del codice html, è la stringa presente nel codice del browser
    codice:
    GET / HTTP/1.1\r\n\r\n
    Stando alle specifiche di HTTP, l'header della request termina alla prima riga vuota, poi ci può essere un body che però è opzionale. Tu questa riga vuota la mandi in output, effettivamente, perché fai \r\n\r\n ovvero CR+LF (per terminare la request line) e poi CR+LF, riga vuota (per terminare l'header).
    Il punto è che nel tuo server questo non lo testi. Verifichi invece la presenza del keep-alive, che un browser reale quasi sicuramente passa ma il "tuo" browser no.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Moderatore di PHP L'avatar di Alhazred
    Registrato dal
    Oct 2003
    Messaggi
    12,505
    Caspita, è vero, ho aggiunto l'output connection keep-alive al browser e funziona.

    Come posso fare sul server la verifica sul doppio ritorno a capo invece che sul keep-alive?
    equals("\r\n\r\n") ovviamente non va.

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da Alhazred Visualizza il messaggio
    Come posso fare sul server la verifica sul doppio ritorno a capo invece che sul keep-alive?
    equals("\r\n\r\n") ovviamente non va.
    Nel server leggi già "a righe" con il readLine. Ti basta verificare che inputLine sia una stringa vuota, ovvero uguale a "" (o length uguale a 0).


    P.S. se ben ricordo la request line+headers andrebbe inviata con charset ASCII ("US-ASCII") ma nel tuo codice client il tuo PrintWriter usa il charset della piattaforma. Magari nel tuo caso specifico va bene, anche se fosse UTF-8 (tanto stai inviando solo roba ascii). Ma in generale bisognerebbe considerare anche questa questione.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

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.