• java网络编程介绍


    前言

      计算机网路实现了多个网络终端的互联,彼此之间能够进行数据交流。而网络应用程序就是在已连接的不同终端设备上运行的程序,这些网络程序相互之间可以进行数据交互。

      网络程序的数据交互则依赖于TCP/IP协议,在实际应用中TCP网络程序提供可靠的数据通信,而UDP网络程序则不保证数据的可靠性,但是协议简单、传输速度快(比如用在音视频数据传输,它们不需要很高的可靠性,偶尔丢帧是可以忍受的)。

    java.net包介绍

    接口摘要

    • ContentHandlerFactory ;此接口定义内容处理程序的工厂。
    • CookiePolicy CookiePolicy 实现决定应该接受哪个 cookie 以及应该拒绝哪个 cookie。
    • CookieStore ;表示 cookie 存储区的 CookieStore 对象。
    • DatagramSocketImplFactory ;此接口定义用于数据报套接字实现的工厂。
    • FileNameMap ;提供在文件名和 MIME 类型字符串之间进行映射的机制的简单接口。
    • SocketImplFactory ;此接口定义用于套接字实现的工厂。
    • SocketOptions ;获取/设置套接字选项的方法的接口。
    • URLStreamHandlerFactory ;该接口为 URL 流协议处理程序定义一个工厂。

    类摘要

    • Authenticator Authenticator 类表示懂得如何获得网络连接验证的对象。
    • CacheRequest ;表示在 ResponseCache 中存储资源的通道。
    • CacheResponse ;表示从 ResponseCache 获取资源的通道。
    • ContentHandler抽象类ContentHandler 是从 URLConnection 读取 Object 的所有类的超类
    • CookieHandler CookieHandler 对象提供一种回调机制以将 HTTP 状态管理策略实现挂钩到 HTTP 协议处理程序。
    • CookieManager CookieManager 提供 CookieHandler 的具体实现,它将 cookie(辨别用户身份的本地终端数据) 的存储区与围绕接受和拒绝 cookie 的策略分离开来。
    • DatagramPacket ;此类表示数据报包。
    • DatagramSocket ;此类表示用来发送和接收数据报包的套接字
    • DatagramSocketImpl ;数据报和多播套接字实现的抽象基类。
    • HttpCookie HttpCookie 对象表示一个 http cookie,该 cookie 带有服务器和用户代理之间的状态信息。
    • HttpURLConnection;支持 HTTP 特定功能的 URLConnection。
    • IDN ;提供在普通 Unicode 表示形式和 ASCⅡ 兼容性编码 (ACE) 表示形式之间进行国际化域名 (IDN) 转换的方法。
    • Inet4Address ;此类表示 Internet Protocol version 4 (IPv4) 地址。
    • Inet6Address ;此类表示互联网协议第 6 版 (IPv6) 地址。
    • InetAddress ;此类表示互联网协议(IP) 地址。
    • InetSocketAddress ;此类实现 IP套接字地址(IP 地址 +端口号)。
    • InterfaceAddress ;此类表示网络接口地址。
    • JarURLConnection ;连接到 Java ARchive (JAR) 文件或 JAR 文件中条目的 URL Connection。
    • MulticastSocket多播数据报套接字类用于发送和接收 IP 多播包。
    • NetPermission ;此类可用于各种网络权限。
    • NetworkInterface ;此类表示一个由名称和分配给此接口的 IP 地址列表组成的网络接口。
    • PasswordAuthentication PasswordAuthentication 类是供 Authenticator 使用的数据持有者。
    • Proxy ;此类表示代理设置,通常为类型(http、socks)和套接字地址。
    • ProxySelector ;连接到 URL 引用的网络资源时选择要使用的代理服务器(如果有)。
    • ResponseCache ;表示 URLConnection 缓存的实现。
    • SecureCacheResponse ;表示最初通过安全方法(如 TLS)获得的缓存响应。
    • ServerSocket ;此类实现服务器套接字。
    • Socket ;此类实现客户端套接字(也可以就叫“套接字”)。
    • SocketAddress ;此类表示不带任何协议附件的 Socket Address。
    • SocketImpl抽象类SocketImpl 是实际实现套接字的所有类的通用超类
    • SocketPermission ;此类表示通过套接字对网络的访问。
    • URI ;表示一个统一资源标识符 (URI) 引用。
    • URL ;类 URL 代表一个统一资源定位符,它是指向互联网“资源”的指针
    • URLClassLoader ;该类加载器用于从指向 JAR 文件和目录的 URL 的搜索路径加载类和资源。
    • URLConnection抽象类URLConnection 是所有类的超类,它代表应用程序和 URL 之间的通信链接。
    • URLDecoder HTML 格式解码的实用工具类。
    • URLEncoder HTML 格式编码的实用工具类。
    • URLStreamHandler抽象类URLStreamHandler 是所有流协议处理程序的通用超类。

    枚举摘要

    • Authenticator.RequestorType ;请求验证的实体的类型。
    • Proxy.Type ;表示代理类型。

    简单的示例

    TCP编程示例

    服务端

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class MyTcpServer {
        private BufferedReader reader;
        private PrintWriter writer;
        private ServerSocket serverSocket;
        private Socket socket;
        private BufferedReader sin;
    
        void  getServer(){
            try {
                serverSocket = new ServerSocket(8866);
                System.out.println("服务器套接字已经创建完成");
    
                while (true){
                    System.out.println("等待客户机的连接");
                    socket = serverSocket.accept();
                    reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    writer = new PrintWriter(socket.getOutputStream(), true);
                    sin=new BufferedReader(new InputStreamReader(System.in));
                    getClientMessage();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        private void getClientMessage(){
            String line ;
            try{
                while(true){
                    System.out.println("客户端信息接收:"+ reader.readLine());
                    writer.println("欢迎您连接服务端");
                    line=sin.readLine();
                    while(!line.equals("bye")){
                        writer.println(line);
                        writer.flush();
                        System.out.println("客户端信息接收:"+ reader.readLine());
                        line=sin.readLine();
                    }
                }
            }catch(Exception e){
                e.printStackTrace();
            }
            try{
                if(reader != null){
                    reader.close();
                }
                if(writer != null){
                    writer.close();
                }
                if(socket != null){
                    socket.close();
                }
            }catch(IOException e){
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
            MyTcpServer myTcpServer = new MyTcpServer();
            myTcpServer.getServer();
        }
    
    }

    客户端

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintWriter;
    import java.net.Socket;
    
    public class MyTcpClient {
        private PrintWriter writer;
        private BufferedReader reader;
        Socket socket;
    
        public void  connect(){
            System.out.println("尝试连接");
            try {
                socket = new Socket("127.0.0.1", 8866);
                writer = new PrintWriter(socket.getOutputStream(),true);
                reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                System.out.println("连接成功");
                writer.println("你好,来自客户端的连接");
                getserverMessage();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        private void getserverMessage(){
            String line ;
            try{
                while(true){
                    System.out.println("服务端信息接收:"+ reader.readLine());
                    BufferedReader sin=new BufferedReader(new InputStreamReader(System.in));
                    line=sin.readLine();
                    while(!line.equals("bye")){
                        writer.println(line);
                        writer.flush();
                        System.out.println("服务端信息接收:"+ reader.readLine());
                        line=sin.readLine();
                    }
                }
            }catch(Exception e){
                e.printStackTrace();
            }
            try{
                if(reader != null){
                    reader.close();
                }
                if(writer != null){
                    writer.close();
                }
                if(socket != null){
                    socket.close();
                }
            }catch(IOException e){
                e.printStackTrace();
            }
        }
        public static void main(String[] args) {
            MyTcpClient tcpclient;
            tcpclient = new MyTcpClient();
            tcpclient.connect();
        }
    
    }

    TCP编程的服务器端一般步骤是: 
      1、创建一个socket,用函数socket(); 
      2、设置socket属性,用函数setsockopt(); * 可选 
      3、绑定IP地址、端口等信息到socket上,用函数bind(); 
      4、开启监听,用函数listen(); 
      5、接收客户端上来的连接,用函数accept(); 
      6、收发数据,用函数send()和recv(),或者read()和write(); 
      7、关闭网络连接; 
      8、关闭监听;

    TCP编程的客户端一般步骤是: 
      1、创建一个socket,用函数socket(); 
      2、设置socket属性,用函数setsockopt();* 可选 
      3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选 
      4、设置要连接的对方的IP地址和端口等属性; 
      5、连接服务器,用函数connect(); 
      6、收发数据,用函数send()和recv(),或者read()和write(); 
      7、关闭网络连接;

    UDP编程示例

    客户端

    import java.io.IOException;
    import java.io.InterruptedIOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    
    public class UDPClient {
        private static final int TIMEOUT = 5000;  //设置接收数据的超时时间
        private static final int MAXNUM = 5;      //设置重发数据的最多次数
        public static void main(String args[]) throws IOException {
            String str_send = "Hello UDPserver";
            byte[] buf = new byte[1024];
            //客户端在9000端口监听接收到的数据
            DatagramSocket ds = new DatagramSocket(9000);
            //获取本地IP
            InetAddress loc = InetAddress.getLocalHost();
            //定义用来发送数据的DatagramPacket实例
            DatagramPacket dp_send= new DatagramPacket(str_send.getBytes(),str_send.length(),loc,3000);
            //定义用来接收数据的DatagramPacket实例
            DatagramPacket dp_receive = new DatagramPacket(buf, 1024);
            //数据发向本地3000端口
            ds.setSoTimeout(TIMEOUT);              //设置接收数据时阻塞的最长时间
            int tries = 0;                         //重发数据的次数
            boolean receivedResponse = false;     //是否接收到数据的标志位
            //直到接收到数据,或者重发次数达到预定值,则退出循环
            while(!receivedResponse && tries<MAXNUM){
                //发送数据
                ds.send(dp_send);
                try{
                    //接收从服务端发送回来的数据
                    ds.receive(dp_receive);
                    //如果接收到的数据不是来自目标地址,则抛出异常
                    if(!dp_receive.getAddress().equals(loc)){
                        throw new IOException("Received packet from an umknown source");
                    }
                    //如果接收到数据。则将receivedResponse标志位改为true,从而退出循环
                    receivedResponse = true;
                }catch(InterruptedIOException e){
                    //如果接收数据时阻塞超时,重发并减少一次重发的次数
                    tries += 1;
                    System.out.println("Time out," + (MAXNUM - tries) + " more tries..." );
                }
            }
            if(receivedResponse){
                //如果收到数据,则打印出来
                System.out.println("client received data from server:");
                String str_receive = new String(dp_receive.getData(),0,dp_receive.getLength()) +
                        " from " + dp_receive.getAddress().getHostAddress() + ":" + dp_receive.getPort();
                System.out.println(str_receive);
                //由于dp_receive在接收了数据之后,其内部消息长度值会变为实际接收的消息的字节数,
                //所以这里要将dp_receive的内部消息长度重新置为1024
                dp_receive.setLength(1024);
            }else{
                //如果重发MAXNUM次数据后,仍未获得服务器发送回来的数据,则打印如下信息
                System.out.println("No response -- give up.");
            }
            ds.close();
        }
    }

    服务端

    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    
    public class UDPService {
        public static void main(String[] args)throws IOException {
            String str_send = "Hello UDPclient";
            byte[] buf = new byte[1024];
            //服务端在3000端口监听接收到的数据
            DatagramSocket ds = new DatagramSocket(3000);
            //接收从客户端发送过来的数据
            DatagramPacket dp_receive = new DatagramPacket(buf, 1024);
            System.out.println("server is on,waiting for client to send data......");
            boolean f = true;
            while(f){
                //服务器端接收来自客户端的数据
                ds.receive(dp_receive);
                System.out.println("server received data from client:");
                String str_receive = new String(dp_receive.getData(),0,dp_receive.getLength()) +
                        " from " + dp_receive.getAddress().getHostAddress() + ":" + dp_receive.getPort();
                System.out.println(str_receive);
                //数据发动到客户端的3000端口
                DatagramPacket dp_send= new DatagramPacket(str_send.getBytes(),str_send.length(),dp_receive.getAddress(),9000);
                ds.send(dp_send);
                //由于dp_receive在接收了数据之后,其内部消息长度值会变为实际接收的消息的字节数,
                //所以这里要将dp_receive的内部消息长度重新置为1024
                dp_receive.setLength(1024);
            }
            ds.close();
        }
    }

    UDP编程的服务器端一般步骤是: 
      1、创建一个socket,用函数socket(); 
      2、设置socket属性,用函数setsockopt();* 可选 
      3、绑定IP地址、端口等信息到socket上,用函数bind(); 
      4、循环接收数据,用函数recvfrom(); 
      5、关闭网络连接;

    UDP编程的客户端一般步骤是: 
      1、创建一个socket,用函数socket(); 
      2、设置socket属性,用函数setsockopt();* 可选 
      3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选 
      4、设置对方的IP地址和端口等属性; 
      5、发送数据,用函数sendto(); 
      6、关闭网络连接;

    总结

      Java提供了Socket和ServerSocket类,让我们可以实现TCP/UDP协议的连接;

      Java还提供了MAIL API,我们可以实现基于SMTP/POP3协议的收发邮件功能;

      最后Java还提供了HttpURLConnection类,用于实现HTTP客户端功能,以及提供了Servlet API用于实现HTTP服务端的编程。

  • 相关阅读:
    JDK1.8源码之HashMap(一)——实现原理、查找及遍历
    JDK1.8源码之ArrayList
    03、Swagger2和Springmvc整合详细记录(爬坑记录)
    02、Java的lambda表达式和JavaScript的箭头函数
    Java-IO流之输入输出流基础示例
    JDBC API 事务的实践
    JDBC API 可滚动可编辑的结果集
    Java虚拟机----垃圾回收与内存分配
    Java数据库连接与查询
    Java虚拟机-对象的创建和访问
  • 原文地址:https://www.cnblogs.com/FondWang/p/12496415.html
Copyright © 2020-2023  润新知