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服务端的编程。

 

posted @ 2019-07-05 20:53  王大军  阅读(341)  评论(0编辑  收藏  举报