套接字编程中的基本控制流

时间:2016-04-09 17:57:34

标签: java sockets flow

我使用套接字编程在Java中创建了一个简单的客户端服务器程序,但是我无法理解该程序的基本控制流程。

客户档案

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

    }



服务器文件

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

如果有人可以在LINE NUMBERS的帮助下,即按声明说明,请向我解释程序的流程,这将非常有帮助。
P.S - 服务器文件的行号从11开始,只是为了方便起见。
谢谢。

3 个答案:

答案 0 :(得分:4)

我理解它的方式,任何服务器/客户端应用程序的常规流程是:

  1. 已建立服务器套接字。

  2. 服务器正在侦听传入连接上的端口23456(阻塞等待)。解除阻塞后,解除阻塞的连接请求将存储在Socket中。

  3. 客户端通过Socket向服务器发送消息,服务器在解除阻塞时立即存储。

  4. 服务器唤醒,因为它收到了一条消息(解除阻塞),并建立了Socket连接。

  5. 服务器从客户端读取消息。 (如果跳过此步骤,客户端通常会感到困惑)。这是通过Socket接受完成的。

  6. 服务器通过接收的Socket写入流生成对客户端的响应并发送它。

  7. 服务器关闭(接受Socket的)输出流以指示通信结束。 (这是必需的)。

  8. 相关示例:

    这是一个相对简单的(不是真的,但我试图尽可能明确)自包含的Web服务器,它可以侦听端口80.运行后,转到http://127.0.0.1:80查看默认页面。在此程序中,客户端是您的Web浏览器(或尝试在localhost 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.");
        }
    }
    

答案 1 :(得分:1)

正如Jose Luis所说,服务器必须具有正确的配置才能连接到客户端,

  

11 - &gt; 12 - &gt; 13 - &gt; 14然后1 - > 2 - &GT; 3 - &GT; 4 - &GT; 5

此后服务器和客户端可以交换信息

看一下这个描述性图片:

enter image description here

答案 2 :(得分:1)

客户端非常简单。它打开一个到服务器的套接字并写入它。

服务器更复杂。第12行在指定端口上创建套接字。第13行将等待客户端连接到该端口并发送消息。然后第16-18行相当简单。他们从套接字中读取消息(由客户端放在那里)并打印出来。