zoukankan      html  css  js  c++  java
  • 随笔 -- IO -- Socket/ServerSocket -- Echo(BIO)实例

    随笔 -- IO -- Socket/ServerSocket -- 系统概述

    Java中提供的专门的网络开发程序包------java.net

    Java的网络编程提供的两种通信协议:TCP和UDP

        19.1 IP与InetAddress

          19.1.1 IP地址简介

          19.1.2 InetAddress

            InetAddress类主要表示IP地址,这个类有两个子类:Inet4Address、Inet6Address。

            InetAddress类的常用方法:

            ⊙ public static InetAddress getByName(String host)throws UnknownHostException :通过主机名称得到InetAddress对象

            ⊙ public static InetAddress getLocalHost() throws UnknownHostException : 通过本机得到InetAddress对象

            ⊙ public String getHostName() : 得到IP地址

            ⊙ public boolean isReachable(int timeout)throws IOException : 判断地址是否可以到达,同时指定超时时间。

    package java_.net_.demo.java_15_5;
    
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    
    public class InetAddressMain {
    
        public static void main(String[] args) throws Exception {
    
            InetAddress locAdd = null;
            InetAddress remAdd = null;
            locAdd = InetAddress.getLocalHost();
            remAdd = InetAddress.getByName("www.baidu.com");
            System.out.println("本机名称 :" + locAdd.getHostName());
            System.out.println("本机IP地址 :" + locAdd.getHostAddress());
            System.out.println("百度IP地址 :" + remAdd);
            System.out.println("本机是否可达 :" + locAdd.isReachable(5000));
            System.out.println("百度是否可达 :" + remAdd.isReachable(5000));
        }
    }

        19.2 URL与URLConnection

          19.2.1 URL

            URL统一资源定位符,可以直接使用此类找到互联网上的资源(如一个简单的网页)。

            URL类的常用方法:

            ⊙ public URL(String spec) throws MalformedURLException : 根据指定的地址实例化URL对象。

            ⊙ public URL(String protocal,String host,int port,String file) throws MalformedURLException : 实例化URL对象,并指定协议、主机、端口名称、资源文件。

            ⊙ public URLConnection openConnection() throws IOException : 取得一个URLConnection对象。

            ⊙ public final InputStream openStream() throws IOException : 取得输入流。

    package java_.net_.demo.java_15_5.URL_;
    
    import java.io.InputStream;
    import java.net.URL;
    import java.util.Scanner;
    
    public class URLMain {
    
        public static void main(String[] args) throws Exception{
            
            URL url = new URL("http","www.mldnjava.cn",80,"/curriculum.htm");
            InputStream input = url.openStream();
            Scanner sc = new Scanner(input);
            sc.useDelimiter("
    ");
            while(sc.hasNext()){
                System.out.println(sc.next());
            }
        }
    }

          19.2.2 URLConnection

            URLConnection是封装访问远程网络资源一般方法的类,通过它可以建立与远程服务器的连接,检查远程资源的一些属性。

            此类的常用方法:

            ⊙ public int getContentLength() : 取得内容的长度。

            ⊙ public String getContentType() : 取得内容的类型。

            ⊙ public InputStream getInputStream() throws IOException : 取得连接的输入流。

            URLConnection对象可以通过URL实例的openConnection()方法取得。

    package java_.net_.demo.java_15_5.URLConnection;
    
    import java.io.InputStream;
    import java.net.URL;
    import java.net.URLConnection;
    import java.util.Scanner;
    
    public class URLConnectionMain {
    
        public static void main(String[] args) throws Exception{
            
            URL url = new URL("http://www.mldnjava.cn");
            URLConnection urlCon = url.openConnection();
            System.out.println("内容大小 :" + urlCon.getContentLength());
            System.out.println("内容类型 :" + urlCon.getContentType());
            InputStream input = urlCon.getInputStream();
            Scanner sc = new Scanner(input);
            sc.useDelimiter("
    ");
            while (sc.hasNext()) {
                System.out.println(sc.next());
            }
        }
    }

        19.3 URLEncoder 与 URLDecoder

          在Java中如果要完成编码和解码操作就必须使用URLEncoder 和 URLDecoder两个类。

          URLEncoder 可以为传递的内容进行编码;URLDecoder可以为传递的内容进行解码。

          URLEncoder类常用的方法:

          ⊙ public static Spring encode(String s,String enc) throws UnsupportedEncodingException : 使用指定的编码机制将字符串转换为application/x-www-form-urlencoded格式。

          URLDecoder类的常用方法:

          ⊙ public static Spring decode(String s,String enc) throws UnsupportedEncodingException : 使用指定的编码机制对application/x-www-form-urlencoded字符串解码。

    package java_.net_.demo.java_15_5.URLEncoder;
    
    import java.net.URLDecoder;
    import java.net.URLEncoder;
    
    public class URLEncoderMain {
    
        public static void main(String[] args) throws Exception{
            
            String keyWord = "lime甲骨文";
            String encod = URLEncoder.encode(keyWord, "UTF-8");
            System.out.println("编码之后的内容 : " + encod);
            String decod = URLDecoder.decode(encod, "UTF-8");
            System.out.println("解码之后的内容 : " + decod);
        }
    }

        19.4 TCP程序设计

          在Java中使用Socket(即套接字)完成TCP程序的开发,使用此类可以方便地简历可靠的、双向的、持续的、点对点的通信连接。

          在Socket的程序开发中,服务器端使用ServerSocket等待客户端连接,对于Java的网络程序来讲,每一个客户端都使用Socket对象表示。

          19.4.1 ServerSocket 类与 Socket 类

            ServerSocket主要用在服务器端程序的开发上,用于接收客户端的连接请求。

            ServerSocket类的常用方法:

            ⊙ public ServerSocket(int port)throws IOException : 创建ServerSocket实例,并指定监听端口。

            ⊙ public Socket accept() throws IOException : 等待客户端连接,此方法连接之前一直阻塞。

            ⊙ public InetAddress getInetAddress() : 返回服务器的IP地址。

            ⊙ public boolean isClosed() : 返回ServerSocket的关闭状态。

            ⊙ public void close() throws IOException : 关闭ServerSocket。

            在服务器端每次运行时都要使用accept()方法等待客户端连接,此方法执行之后服务器端将进入阻塞状态,知道客户端连接之后程序可以向下继续执行。此方法返回值类型是Socket,每一个Socket都表示一个客户端对象。

            Socket类的常用方法:

            ⊙ public Socket(String host,int port) throws UnknownHostException,IOException  : 构造Socket对象,同时指定要连接服务器的主机名称及连接端口。

            ⊙ public InputStream getInputStream() throws IOException : 返回此套接字的输入流。

            ⊙ public OutputStream getOutputStream() throws IOException : 返回此套接字的输入流。

            ⊙ public void close() throws IOException : 关闭此Socket。

            ⊙ public boolean isClosed() : 判断此套接字是否被关闭。

            在客户端,程序可以通过Socket类的getInputStream()方法取得服务器的输入信息,在服务器端可以通过getOutputStream()方法取得客户端的输出信息。

          19.4.2 第一个TCP程序

            Class : ServerSocketMain

    package java_.net_.demo.java_15_5.serverSocket;
    
    import java.io.PrintStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.Date;
    
    public class ServerSocketMain {
    
        public static void main(String[] args) throws Exception{
            
            ServerSocket server = new ServerSocket(8888);
            Socket client = null;
            PrintStream out = null;
            int count = 1;
            while(true){
                System.out.println("等待第 " + count + " 个客户端接入");
                client = server.accept();
                System.out.println("第 " + count + " 个客户端已接入");
                count++;
                String resp = "Now is : " + new Date();
                out = new PrintStream(client.getOutputStream());
                out.println(resp);
            }
        }
    }

            Class : SocketMain

    package java_.net_.demo.java_15_5.socket;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.net.Socket;
    
    public class SocketMain {
    
        public static void main(String[] args) throws Exception{
            Socket client = new Socket("localhost",8888);
            BufferedReader buf = null;
            buf = new BufferedReader(new InputStreamReader(client.getInputStream()));
            String str = buf.readLine();
            System.out.println("服务器端输出内容 :" + str);
            client.close();
            buf.close();
        }
    }

          19.4.3 案例:Echo程序(BIO)

            Echo程序是一个网络编程通信交互的一个经典案例,称为回应程序,即客户端输入那些内容,服务器端会在这些内容前加上“ECHO:”并将信息发回客户端。

            本程序中将通过循环的方式使用accept(),这样,每一个客户端执行完毕后,服务器端都可以重新等待用户连接。

              Class : EchoServer

    package limeNet.server;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.io.PrintStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class EchoServer {
    
        public static void main(String[] args) throws Exception {
            ServerSocket server = null;
            Socket client = null;
            PrintStream out = null;
            BufferedReader buf = null;
            server = new ServerSocket(8888);
            boolean f = true;
            while(f){
                System.out.println("服务器运行,等待客户端连接。");
                client = server.accept();
                buf = new BufferedReader(new InputStreamReader(client.getInputStream()));
                out = new PrintStream(client.getOutputStream());
                boolean flag = true;
                while(flag){
                    String str = buf.readLine();
                    if(null == str || "".equals(str)){
                        flag = false;
                    }else{
                        if("bye".equals(str)){
                            flag = false;
                        }else{
                            out.print("ECHO : " + str);
                        }
                    }
                }
                out.close();
                buf.close();
                client.close();
            }
            server.close();
        }
    }

              Class : EchoClient

    package limeNet.client;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.io.PrintStream;
    import java.net.Socket;
    
    public class EchoClient {
    
        public static void main(String[] args) throws Exception, Exception {
            Socket client = null;
            client = new Socket("localhost",8888);
            BufferedReader input = null;
            PrintStream out = null;
            BufferedReader buf = null;
            input = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintStream(client.getOutputStream());
            buf = new BufferedReader(new InputStreamReader(client.getInputStream()));
            boolean flag = true;
            while(flag){
                System.out.print("输入信息:");
                String str = input.readLine();
                out.print(str);
                if("bye".equals(str)){
                    flag = false;
                }else{
                    String echo = buf.readLine();
                    System.out.println(echo);
                }
            }
            client.close();
            buf.close();
        }
    }

          19.4.4 在服务器上应用多线程

            对于服务器端来说,如果要加入多线程机制,则应该在每个用户连接之后启动一个新的线程。

            Class : EchoThread

    package limeNet.thread.server;
    
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.net.Socket;
    
    public class EchoThread implements Runnable {
    
        private Socket accept;
    
        public EchoThread() {
            super();
        }
        public EchoThread(Socket accept) {
            super();
            this.accept = accept;
        }
    
        public void run() {
            DataInputStream in = null;
            DataOutputStream out = null;
            try {
                in = new DataInputStream(accept.getInputStream());
                out = new DataOutputStream(accept.getOutputStream());
                boolean goon = true;
                while (goon) {
                    String str = in.readUTF();
                    if (null == str || "".equals(str)) {
                        goon = false;
                    } else {
                        if ("bye".equalsIgnoreCase(str)) {
                            goon = false;
                        } else {
                            out.writeUTF("ECHO:" + str);
                        }
                    }
                }
                in.close();
                out.close();
                accept.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

            Class : EchoThreadServer

    package limeNet.thread.server;
    
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class EchoThreadServer {
    
        public static void main(String[] args) throws Exception {
            ServerSocket serverSocket = new ServerSocket(8888);
            while(true){
                System.out.println("服务器运行,等待客户端连接。");
                Socket accept = serverSocket.accept();
                new Thread(new EchoThread(accept)).start();
            }
        }
    }

            Class : EchoClient

    package limeNet.client;
    
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.net.Socket;
    import java.util.Scanner;
    
    public class EchoClient {
    
        public static void main(String[] args) throws Exception, Exception {
            Socket client = null;
            client = new Socket("localhost",8888);
            DataInputStream in = null;
            DataOutputStream out = null;
            in = new DataInputStream(client.getInputStream());
            out = new DataOutputStream(client.getOutputStream());
            Scanner sc = new Scanner(System.in);
            boolean flag = true;
            while(flag){
                System.out.print("输入信息:");
                String str = sc.nextLine();
                out.writeUTF(str);                                                                                                      
                if("bye".equals(str)){
                    flag = false;
                }else{
                    String echo = in.readUTF();
                    System.out.println(echo);
                }
            }
            in.close();
            out.close();
            sc.close();
            client.close();
        }
    }

        19.5 UDP程序设计

          19.5.1 UDP简介

          19.5.2 UDP程序实现

            Class : UDPClient

    package limeNet.udp.client;
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    
    public class UDPClient {
    
        public static void main(String[] args) throws IOException {
            DatagramSocket ds = new DatagramSocket(9000);
            byte[] buf = new byte[1024];
            DatagramPacket dp = new DatagramPacket(buf, 1024);
    //        阻塞
            ds.receive(dp);
            String str = new String(dp.getData(),0,dp.getLength()) + "from " + dp.getAddress().getHostAddress() + " : " + dp.getPort();
            System.out.println(str);
            ds.close();
        }
    }

            Class : UDPServer

    package limeNet.udp.server;
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    
    public class UDPServer {
    
        public static void main(String[] args) throws IOException {
            DatagramSocket ds = null;
            DatagramPacket dp = null;
            ds = new DatagramSocket(3000);
            String str = "Hello World";
            dp = new DatagramPacket(str.getBytes(), str.length(),InetAddress.getByName("localhost"),9000);
            System.out.println("发送信息。");
            ds.send(dp);
            ds.close();
        }
    }

    啦啦啦

    啦啦啦

    啦啦啦

    啦啦啦

    啦啦啦

    啦啦啦

    啦啦啦

    啦啦啦

  • 相关阅读:
    钟国晨160809323(作业5)
    12
    11
    第九次
    8作业
    第七次作业
    6
    林昊5
    计算机网络原理与应用笔记 3/29
    计算机网络原理与应用笔记 3/22
  • 原文地址:https://www.cnblogs.com/ClassNotFoundException/p/6306269.html
Copyright © 2011-2022 走看看