2016-04-09 3 views
1

Ich habe ein einfaches Client-Server-Programm in Java mit Socket-Programmierung gemacht, aber ich bin nicht in der Lage, den grundlegenden Ablauf der Kontrolle des Programms zu verstehen.Grundlegender Fluss der Kontrolle in Socket Programmierung

Client-Datei

public static void main(String args[]) throws UnknownHostException, IOException, InterruptedException{ 
     1. System.out.println("CLIENT: "+"client main method started"); 

     2. Socket s=new Socket("localhost",23456); 

     3. BufferedWriter br=new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); 

     4. br.write("CLIENT: "+"here comes the client message"); 

     5.br.flush(); 

    } 



Server Datei

public static void main(String args[]) throws IOException, InterruptedException{ 

     11. System.out.println("Server is started"); 

     12. ServerSocket ser=new ServerSocket(23456); 

     13. Socket s=ser.accept(); 

     14. System.out.println("SERVER: "+"Server is now accepting connections"); 

     15. System.out.println("SERVER: "+"client connected"); 

     16. BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream())); 

     17. String str=br.readLine(); 

     18. System.out.println("SERVER: "+"Client Message: "+str); 
    } 


Es wäre wirklich hilfreich, wenn jemand mir den Ablauf des Programms mit Hilfe erklären bitte könnte von LINE NUMBERS dh durch Aussage nach Aussage.
P.S - Zeilennummer für Serverdatei beginnt mit 11, nur aus Gründen der Bequemlichkeit.
Danke.

+0

(1) Bitte geben Sie vollständige in sich geschlossene Code-Schnipsel, so dass die antwortenden Personen in der Lage sein zu testen, was sie sagen, gültig ist. – Dmitry

+0

Erstens: 11,12,13,14 (zu diesem Zeitpunkt könnte der Client eine Verbindung herstellen). Zweitens: 1,2,3,4,5 (Client sendet Informationen an den Server). Drittens: 15,16,17,18 (Server liest Client-Informationen und macht etwas). –

Antwort

4

So wie ich es verstehe, der regelmäßige Fluss von jedem Server/Client-Anwendung ist:

  1. Der Server-Socket hergestellt wird.

  2. Der Server überwacht Port 23456 bei eingehenden Verbindungen (Blockierung wartet). Nach dem Entsperren wird die Verbindungsanforderung, die sie entsperrt hat, in einem Socket gespeichert.

  3. Der Client sendet eine Nachricht an den Server über einen Socket, den der Server beim Entsperren sofort speichert.

  4. Der Server wacht auf, weil er eine Nachricht erhält (entsperrt) und die Socket-Verbindung hergestellt ist.

  5. Der Server liest die Nachricht vom Client. (Wenn Sie diesen Schritt überspringen, wird der Client normalerweise verwirrt). Dies geschieht über den Socket accepted.

  6. Der Server generiert eine Antwort an den Client und sendet sie über einen Schreibstream des Sockets akzeptiert.

  7. Der Server schließt den Ausgabestrom (Socket akzeptiert), um das Ende der Kommunikation anzuzeigen. (Dies ist erforderlich).

Für ein ähnliches Beispiel:

hier ein relativ einfach ist (nicht wirklich, aber ich versuchte, so explizit wie ich konnte zu sein) in sich geschlossene Web-Server, der auf Port lauscht 80. Sobald Sie es laufen, Gehe zu http://127.0.0.1:80, um die Standardseite zu sehen. In diesem Programm ist der Client Ihren Web-Browser (oder jedes andere Programm, das auf localhost 80 zu hören versucht)

import java.net.*; 
import java.io.*; 
import java.util.*; 
import java.util.regex.*; 
import javax.swing.*; 
import java.awt.*; 
import jserv.*; 

public class JavaServer 
{ 
    public static void main(String[] args) 
     throws Exception 
    { 
     ServerSocket server = null; 
     Socket conn = null; 
     BufferedReader in = null; 
     PrintWriter out = null; 
     String msg = null; 
     ArrayList<String> tcp_get = null; 

     System.out.println("server> Starting!"); 

     server = new ServerSocket(80);   

     while (true) { 
      System.out.println("server> Waiting on a connection."); 

      conn = server.accept(); 

      System.out.println("server> Obtaining io handles."); 

      out = new PrintWriter(conn.getOutputStream(), true);   
      in = new BufferedReader (
       new InputStreamReader (
        conn.getInputStream() 
       ) 
      ); 

      System.out.println("server> We get signal."); 

      while ((msg = in.readLine()) != null) { 
       System.out.println("  " + msg); 

       /* done if empty line or null. */ 
       if (msg.isEmpty()) { 
        System.out.println("-- all client info is read --"); 
        break; 
       } 

       /* additional protocol handling. */ 
       if (msg.startsWith("GET")) { 
        tcp_get = get_decode(msg); 
       } 
      } 

      System.out.println("server> sending a message to client.");   

      /* send the HTML data. acknowledge? */ 
      /* header */ 
      out.write("HTTP/1.0 200 OK\r\n"); 
      out.write("Content-Type: text/html\r\n"); 
      out.write("\r\n"); 

      /* response division. */ 
      System.out.println("tcp_get empty: " + tcp_get.isEmpty()); 
      if (!tcp_get.isEmpty()) { 
       String page = tcp_get.get(0); 

       /* we have a page request. */ 
       if (isValidPage(page)) { 
        File f = new File(page); 

        try { 
         Scanner br = new Scanner(new FileInputStream(f)); 
         String s; 

         while ((s = br.nextLine()) != null) { 
          out.write(s + "\r\n"); 
         } 

         br.close(); 

         out.write("\r\n"); 
         System.out.println("server> closing stream.");   
        } catch (FileNotFoundException e) {     
         out.write("<p>ERROR 404!</p>\r\n"); 
         out.write("\r\n"); 
         System.out.println("sent default message."); 
        } catch (Exception e) {} 
       } 
       /* once the stream is closed, the client will receive the data."); */ 
      } else { 
       out.write("<p>Welcome to the default page!</p>\r\n"); 
       out.write("\r\n"); 
      } 
      out.close(); 

      System.out.println("server> end of communication.");   
     } 
    } 

    private static boolean isValidPage(String page) 
    { 
     Pattern pat = Pattern.compile("\\w+\\.html"); 
     Matcher mat = pat.matcher(page); 

     return mat.matches(); 
    } 

    private static ArrayList<String> get_decode(String get) 
    { 
     ArrayList<String> tmp = new ArrayList<String>(); 
     Pattern pat; 
     Matcher mat; 
     String page; 

     String page_pattern = "\\w+\\.html"; 
     String arg_pattern = "\\w+=\\w+"; 
     String gt = get.replaceFirst(page_pattern, "");  

     /* obtain the page name. */   
     pat = Pattern.compile(page_pattern); 
     mat = pat.matcher(get); 

     if (!mat.find()) { 
      System.out.println("decode> GET invalid.");  
      return tmp; 
     } else { 
      page = mat.group(); 
      System.out.println("GET requests " + page);    
      tmp.add(page); 
     } 

     /* strip name from get. */ 
     gt = get.replaceFirst(page_pattern, "");   

     /* obtain the arguments. */ 
     pat = Pattern.compile(arg_pattern); 
     mat = pat.matcher(gt); 

     while (mat.find()) { 
      System.out.println("argument: " + mat.group()); 
      tmp.add(mat.group()); 
     }   

     return tmp; 
    } 
} 

Als Antwort auf Ihre eigentlichen Code, bitte auf diesen Code in Bezug auf die 7 Punkte zurückblicken I aufgelistet.

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

class Client { 
    public static void main(String args[]) throws Exception {   
     System.out.println("client> started."); 
     Socket s = new Socket("localhost", 23456); 
     BufferedWriter br = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); 
     // all messages must end with two linefeeds. 
     br.write("hello, world!\n\n"); 
     // two linefeeds with no messages indicates end. 
     br.write("\n\n"); 

     // see part 7. closing the stream flushes the output. 
     br.close(); 
    } 
} 

class Server { 
    public static void main(String args[]) throws Exception { 
     ServerSocket ser = null; 
     Socket s = null; 
     BufferedReader br = null; 
     String str = null; 

     System.out.println("server> started"); 
     ser = new ServerSocket(23456); 
     s = ser.accept(); 
     System.out.println("server> we get signal.");     
     br = new BufferedReader(new InputStreamReader(s.getInputStream())); 
     while ((str = br.readLine()) != null) { 
      if (str.isEmpty()) { 
       System.out.println("server> everything is received."); 
       break; 
      } 
      System.out.println("server> got message: " + str); 
     } 
     System.out.println("server> done."); 
    } 
} 
+0

Vielen Dank für diese Punkte (viel geklärt). Was nun, wenn der Client niemals eine Nachricht an den Server sendet, wird er immer auf Zeile 15 warten, bis die Verbindung geschlossen wird? Auch was macht flush()? –

+1

Das macht ein Server. Es blockiert auf dem Server (oder in einigen Fällen, beschäftigt-Schleifen) für immer, bis jemand eine Anfrage stellt. Es macht dies immer wieder und typischerweise, anstatt es zu behandeln, erstellt einen Thread, der es für sie tut. Ein typischer Server ist sehr faul, und seine Aufgabe ist es, jede einzelne Anfrage zu bestätigen, mit der er oft zu kämpfen hat (stellen Sie sich vor, dass eine Million Leute versuchen, eine Webseite auf einmal anzufordern), daher muss sie faul sein). – Dmitry

+0

Vielen Dank. Alles macht jetzt viel mehr Sinn: D. –

1

als Jose Luis sagte, muß Server eine einwand Konfiguration aufweist, um mit einem Client verbunden zu werden,

11 -> 12 -> 13 -> 14, dann 1 -> 2- -> 3 -> 4 -> 5

danach der Server und der Client-Informationen austauschen können

werfen Sie einen Blick auf diese beschreibende Bild:

enter image description here

1

Der Client ist ziemlich einfach. Es öffnet einen Socket zum Server und schreibt darauf.

Der Server ist komplexer. Zeile 12 erstellt den Socket am angegebenen Port. Zeile 13 wartet, bis ein Client eine Verbindung zu diesem Port herstellt und eine Nachricht sendet. Dann sind die Zeilen 16-18 ziemlich einfach. Sie lesen die Nachricht vom Socket (die vom Client dorthin gestellt wurde) und drucken sie aus.

+0

Vielen Dank. Was passiert, wenn ich nie eine Nachricht vom Client an den Server sende, wird der Server in Zeile 15 anhalten? –

+0

@ Brut3Forc3 Ich bin mir ziemlich sicher, dass das stimmt, aber Sie können es immer ausprobieren und sehen! – nhouser9

+0

Ich habe es versucht, aber leider scheint es, dass der Server nie auf eine Ausgabenachricht vom Client wartete, da alle Anweisungen im Server ausgeführt wurden, selbst wenn ich die Zeilen 3, 4 und 5 vom Client auskommentierte. –