2016-04-09 4 views
1

Я создал простую клиентскую серверную программу на Java с помощью Socket Programming, но я не могу понять основной поток управления программой.Базовый поток управления в программировании сокетов

файл клиента

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(); 

    } 



File Server

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); 
    } 


Было бы очень полезно, если кто-то может пожалуйста, объясните мне поток программы с помощью ЛИНЕЙНЫЕ НОМЕРА, т. Е. По заявлению.
P.S - Номер строки для файла сервера начинается с 11, только для удобства.
Спасибо.

+0

(1) Просьба предоставить полные самодостаточные фрагменты кода, чтобы пользователи, отвечающие, могли проверить, что они говорят. – Dmitry

+0

Первый: 11,12,13,14 (на данный момент клиент может подключиться). Второе: 1,2,3,4,5 (клиент отправляет информацию на сервер). Третье: 15,16,17,18 (сервер читает информацию о клиенте и что-то делает). –

ответ

4

Я так понимаю, регулярный поток любого клиента/сервера приложения: устанавливаются

  1. сокета сервера.

  2. Сервер прослушивает порт 23456 при входящих соединениях (блокировка ожидания). Как только он разблокируется, запрос на соединение, который разблокирован, хранится внутри Socket.

  3. Клиент отправляет сообщение серверу через Socket, который сервер сразу же сохраняет при его разблокировке.

  4. Сервер просыпается, потому что он получил сообщение (разблокирует), и установлено соединение сокета.

  5. Сервер считывает сообщение от клиента. (Если вы пропустите этот шаг, клиент обычно путается). Это делается с помощью Socket.

  6. Сервер генерирует ответ клиенту и отправляет его через поток записи принятого Socket.

  7. Сервер закрывает выходной поток (принимаемого сокета), чтобы указать конец связи. (Это необходимо).

Для соответствующего примера:

Вот относительно простой (не очень, но я старался быть как явными, как я мог) себе содержало веб-сервер, который прослушивает порт 80. После того, как вы запустите его, перейдите на страницу http://127.0.0.1:80, чтобы просмотреть страницу по умолчанию. В этой программе, клиент ваш веб-браузер (или любая другая программа, которая пытается слушать на локальном хосте 80)

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; 
    } 
} 

В ответ на ваш фактический код, пожалуйста, посмотрите на этот код по отношению к 7 очков я в списке.

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

Спасибо за эти моменты (прояснилось много). Теперь, что, если клиент никогда не отправит сообщение на сервер, будет ли он продолжать ждать на линии 15 до закрытия соединения? И что делает flush()? –

+1

Это то, что делает сервер. Он блокирует на сервере (или, в некоторых случаях, циклы занятости) навсегда, пока кто-то не сделает запрос. Он делает это снова и снова, и обычно вместо того, чтобы обрабатывать его, создает поток, который делает это для них. Типичный сервер очень ленив, и его задача - признать каждый отдельный запрос, с которым он часто сталкивается (представьте, что миллион человек пытается запросить веб-страницу сразу), поэтому он должен быть ленивым). – Dmitry

+0

Спасибо большое. Теперь все имеет смысл: D. –

1

Как сказал Хосе Луис, сервер должен иметь конфигурацию должным образом для того, чтобы быть подключен к клиенту,

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

после этого клиент и сервер могут обмениваться информацией

посмотрите на этот описательный изображение:

enter image description here

1

Клиент довольно прост. Он открывает сокет для сервера и записывает на него.

Сервер более сложный. Строка 12 создает сокет на указанном порту. Строка 13 будет ждать, пока клиент подключится к этому порту и отправит сообщение. Тогда строка 16-18 довольно проста. Они читают сообщение из сокета (которое было установлено клиентом) и распечатывают его.

+0

Спасибо большое. Что делать, если я никогда не отправлю сообщение от клиента на сервер, остановится ли сервер в строке 15? –

+0

@ Brut3Forc3 Я уверен, что это правильно, но вы всегда можете попробовать и посмотреть! – nhouser9

+0

Я пробовал, но, к сожалению, сервер никогда не ожидал выходного сообщения от клиента, поскольку все операторы на сервере выполнялись, даже когда я прокомментировал строки 3, 4 и 5 от клиента. –

Смежные вопросы