JAVA SE 网络编程

网络基础

IP地址:用于区分网络上每一台主机。

网络协议:IPV4、IPV6。用于统一通信语言标准。

端口号:0~65535,(0~1023内定)用于区分计算机上的不同程序。

TCP/IP协议:应用最广的协议。TCP(传输控制协议),IP(互联网协议)

网络编程:程序通过网络进行连接。位于java.net包中

java.net 包中提供了两种常见的网络协议的支持:

  • TCP:传输控制协议,保障了应用程序之间的可靠通信。常用于互联网协议,被称 TCP / IP
  • UDP:用户数据报协议,一个无连接的协议。提供了应用程序之间要发送的数据的数据报

java网络编程中的四大类

  • InetAddress:用于表示IP地址
  • URL:读写网络资源
  • Socket:实现网络通信(TCP)
  • Datagram:保存数据报中,进行通信(UDP)

InetAddress类

常用方法

  • static InetAddress getLocalHost() //返回本地主机实例
  • static InetAddress getByAddress(byte[] addr) //输入ip地址,返回对应主机实例
  • static InetAddress getByName(String host) //输入主机名,返回对应主机实例
  • static InetAddress getByAddress(String host, byte[] addr) //输入主机名,ip地址,返回主机实例
  • byte[] getAddress() //返回主机ip地址
  • String getHostAddress() //返回主机地址
  • String getHostName() //返回主机名
  • boolean isAnyLocalAddress() //检查 InetAddress 是否是通配符地址的实用例行程序。
  • boolean isLinkLocalAddress() //检查 InetAddress 是否是链接本地地址的实用例行程序。
  • boolean isLoopbackAddress() //检查 InetAddress 是否是回送地址的实用例行程序。

URL

统一资源定位符:表示网络上资源,它是指向互联网“资源”的指针。

eg.:协议 : 资源名

https://www.baidu.com/index.html

构造方法:

  • URL(String spec)
  • URL(String protocol, String host, int port, String file)
  • URL(String protocol, String host, int port, String file, URLStreamHandler handler)
  • URL(String protocol, String host, String file)
  • URL(URL context, String spec)
  • URL(URL context, String spec, URLStreamHandler handler)

eg.:

URL test = new URL("http://www.baidu.com");

URL url = new URL(test,"/index.html?username=tom#test");// #后面表示锚点,?后面表示参数

常用方法:

  • Object getContent() //获取此URL内容
  • int getDefaultPort() //获取此URL默认端口
  • int getPort() //获取此端口,没有指定则默认-1
  • String getFile() // 获取此URL文件名
  • String getHost() //获取主机名
  • String getPath() //获取该路径
  • String getProtocol() //获取此协议名
  • String getQuery() //获取URL查询部分
  • String getRef() //获取URL的锚点(引用),获取相对路径
  • String getUserInfo() //获取URL的userInfo部分
  • URLConnection openConnection() //URL 所引用的远程对象的连接。
  • InputStream openStream() //打开此 URL连接,返回从该连接读入的 InputStream
  • protected void set(String protocol, String host, int port, String file, String ref) //设置 URL 的字段

实例应用——获取网页信息

//获取网页信息
import java.io.*;
import java.net.*;
public class TestURL {
    public static void main(String[] args) {
        InputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        try {
            URL url = new URL("http://www.baidu.com");
            inputStream = url.openStream();//获取网页的字节流
            inputStreamReader = new InputStreamReader(inputStream, "utf-8");//转化为字符流
            bufferedReader = new BufferedReader(inputStreamReader);//提高读写效率
            String data = bufferedReader.readLine();
            while (data != null) {
                System.out.println(data);
                data = bufferedReader.readLine();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (bufferedReader != null) {
                    bufferedReader.close();
                }
                if (inputStreamReader != null) {
                    inputStreamReader.close();
                }
                if (inputStream != null) {
                    inputStream.close();
                }
            } catch (Exception e) {
            }
        }
    }
}

基于TCP的socket编程(有序,有连接,可靠)

套接字使用TCP提供了两台计算机之间的通信机制。

主要类有

  • Socket:客户端
  • ServerSocket:服务端

ServerSocket类

java.net.ServerSocket 类以获取一个端口,并且侦听客户端请求。

构造方法

  • ServerSocket()//创建非绑定服务器套接字
  • ServerSocket(int port) //创建绑定到特定端口的服务器套接字
  • ServerSocket(int port, int backlog) //指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号
  • ServerSocket(int port, int backlog, InetAddress address) //使用指定的端口、侦听 backlog 和要绑定到的本地 IP 地址创建服务器

常用方法

  • Socket accept()//侦听并接受到此套接字的连接
  • void bind(SocketAddress endpoint) //将 ServerSocket 绑定到特定地址
  • void bind(SocketAddress host, int backlog) //将 ServerSocket 绑定到特定地址
  • int getLocalPort() //返回此套接字在其上侦听的端口
  • boolean isBound() //返回 ServerSocket 的绑定状态
  • boolean isClosed() //返回 ServerSocket 的关闭状态
  • static void setSocketFactory(SocketImplFactory fac) //设置服务器套接字实现工厂
  • void setSoTimeout(int timeout) //通过指定超时值启用/禁用 SO_TIMEOUT

Socket类

java.net.Socket 类代表客户端和服务器都用来互相沟通的套接字,套接字是两台机器间通信的端点。

关闭时,io流同时关闭。

构造方法

  • Socket() //系统默认 SocketImpl 创建未连接套接字
  • Socket(InetAddress host, int port)//创建套接字并连接到指定 IP 地址的指定端口号
  • Socket(String host, int port) //连接到指定主机上的指定端口号
  • Socket(Proxy proxy) //创建一个未连接的套接字并指定代理类型
  • Socket(String host, int port, InetAddress localAddr, int localPort) //连接到指定远程主机上的指定远程端口
  • Socket(InetAddress host, int port, InetAddress localAddr, int localPort) //连接到指定远程主机上的指定远程端口

常用方法

  • void bind(SocketAddress bindpoint) //绑定到本地地址
  • void connect(SocketAddress endpoint) //连接到服务器
  • void connect(SocketAddress endpoint, int timeout) //连接到服务器,并指定一个超时值
  • SocketChannel getChannel() //返回与此数据报关联的唯一 SocketChannel 对象
  • InetAddress getInetAddress() //返回套接字连接的地址
  • InputStream getInputStream() //返回此套接字的输入流
  • OutputStream getOutputStream() //返回此套接字的输出流
  • SocketAddress getRemoteSocketAddress() //返回此套接字连接的端点的地址

实例应用——单线程

//服务端

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
//服务端
public class Server {
    public static void main(String[] args) {
        try {
            //1.创建server实例并绑定端口
            ServerSocket serverSocket = new ServerSocket(6666);
            System.out.println("***服务端开始启动,等待客户端的连接***");
            //2.调用accept(),监听客户端请求
            Socket socket = serverSocket.accept();
            //3.读取客户端请求信息
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String info = null;
            while ((info = bufferedReader.readLine()) != null) {
                System.out.println("客户端说:" + info);
            }
            socket.shutdownInput();
            //4.输出服务端响应信息
            OutputStream outputStream = socket.getOutputStream();
            PrintWriter printWriter = new PrintWriter(outputStream);
            printWriter.write("欢迎使用!");
            printWriter.flush();
            //5.关闭相关资源
            printWriter.close();
            outputStream.close();
            bufferedReader.close();
            socket.close();
            serverSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

//客户端 

import java.io.*;
import java.net.Socket;
//客户端
public class Client {
    public static void main(String[] args) {
        try {
            //1.创建socket实例,并连接服务端
            Socket socket = new Socket("localhost", 6666);
            //2.建立连接后,发出请求
            OutputStream outputStream = socket.getOutputStream();
            PrintWriter printWriter = new PrintWriter(outputStream);
            printWriter.write("用户名:max ; 密码:123");
            printWriter.flush();
            socket.shutdownOutput();
            //3.获取服务端响应信息
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String info = null;
            while ((info = bufferedReader.readLine()) != null) {
                System.out.println("服务端说:" + info);
            }
            //4.关闭相关资源
            bufferedReader.close();
            printWriter.close();
            outputStream.close();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

实例应用——多线程

//线程类

import java.io.*;
import java.net.Socket;

public class ServerThread extends Thread {
    Socket socket = null;

    public ServerThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        BufferedReader bufferedReader = null;
        OutputStream outputStream = null;
        PrintWriter printWriter = null;
        try {
            //3.读取客户端请求信息
            bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String info = null;
            while ((info = bufferedReader.readLine()) != null) {
                System.out.println("客户端说:" + info);
            }
            socket.shutdownInput();

            //4.输出服务端响应信息
            outputStream = socket.getOutputStream();
            printWriter = new PrintWriter(outputStream);
            printWriter.write("欢迎使用!");
            printWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //5.关闭相关资源
            try {
                if (printWriter != null)
                    printWriter.close();
                if (outputStream != null)
                    outputStream.close();
                if (bufferedReader != null)
                    bufferedReader.close();
                if (socket != null)
                    socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

//服务端

import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public static void main(String[] args) {
        try {
            //1.创建server实例并绑定端口
            ServerSocket serverSocket = new ServerSocket(6666);
            //2.调用accept(),监听客户端请求
            int count = 0;//客户端数量
            System.out.println("***服务端开始启动,等待客户端的连接***");
            //循环监听
            while (true) {
                Socket socket = serverSocket.accept();
                ServerThread serverThread = new ServerThread(socket);
                serverThread.start();
                count++;
                System.out.println("输出客户端连接的数量:"+count);
                InetAddress address = socket.getInetAddress();
                System.out.println("当前客户端ip:"+address);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

基于UDP的socket编程(无序、无连接、不可靠)

定义数据报Datagram,在数据报中指明数据要到达的socket(主机、端口),再发出。速度较快

主要类有:

  • DatagramPacket:数据报包
  • DatagramSocket:进行端对端通信

DatagramPacket类

数据报包用来实现无连接包投递服务。

每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。

从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。不对包投递做出保证。

构造方法

  • DatagramPacket(byte[] buf, int length) //用来接收长度为 length 的数据包。
  • DatagramPacket(byte[] buf, int length, InetAddress address, int port) //用来将长度为 length 的包发送到指定主机上的指定端口
  • DatagramPacket(byte[] buf, int offset, int length) //构造 DatagramPacket,用来接收长度为 length 的包,在缓冲区中指定了偏移量
  • DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port) //将长度为 length 偏移量为 offset 的包发送到指定主机上的指定端口号。
  • DatagramPacket(byte[] buf, int offset, int length, SocketAddress address) //将长度为 length 偏移量为 offset 的包发送到指定主机上的指定端口号。
  • DatagramPacket(byte[] buf, int length, SocketAddress address) //将长度为 length 的包发送到指定主机上的指定端口号。

常用方法

  • InetAddress getAddress() //返回某台机器的 IP 地址
  • byte[] getData() //返回数据缓冲区
  • int getLength() //返回将要发送或接收到的数据的长度
  • int getOffset() //返回将要发送或接收到的数据的偏移量
  • SocketAddress getSocketAddress() //获取此数据报的远程主机的 SocketAddress
  • void setAddress(InetAddress iaddr) 设置要将此数据报发往的那台机器的 IP 地址
  • void setData(byte[] buf) //为此包设置数据缓冲区。
  • void setData(byte[] buf, int offset, int length) //为此包设置数据缓冲区。
  • void setLength(int length) //为此包设置长度。
  • void setPort(int iport) //设置要将此数据报发往的远程主机上的端口号。
  • void setSocketAddress(SocketAddress address) //设置远程主机的 SocketAddress

DatagramSocket类

数据报套接字是包投递服务的发送或接收点。每个在数据报套接字上发送或接收的包都是单独编址和路由的。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。

构造方法

  • DatagramSocket() //绑定到本地主机上任何可用的端口
  • DatagramSocket(DatagramSocketImpl impl) //指定 DatagramSocketImpl 未绑定数据报
  • DatagramSocket(int port) //绑定到本地主机上的指定端口
  • DatagramSocket(int port, InetAddress laddr) //绑定到指定的本地地址
  • DatagramSocket(SocketAddress bindaddr) //绑定到指定的本地套接字地址

常用方法

  • void bind(SocketAddress addr) //将此 DatagramSocket 绑定到特定的地址和端口
  • void connect(InetAddress address, int port) //将套接字连接到此套接字的远程地址
  • void connect(SocketAddress addr) //连接到远程套接字地址(IP 地址 + 端口号)
  • void disconnect() //断开套接字的连接
  • DatagramChannel getChannel() //返回关联DatagramChannel 对象(如果有)。
  • InetAddress getInetAddress() //返回此套接字连接的地址。
  • InetAddress getLocalAddress() //获取套接字绑定的本地地址。
  • int getLocalPort() //返回此套接字绑定的本地主机上的端口号。
  • SocketAddress getLocalSocketAddress() //绑定的端点的地址,未绑定则返回 null。
  • int getPort() //返回此套接字的端口
  • boolean isBound() //返回套接字的绑定状态。
  • boolean isClosed() //返回是否关闭了套接字。
  • boolean isConnected() //返回套接字的连接状态。
  • void receive(DatagramPacket p) //从此套接字接收数据报包。
  • void send(DatagramPacket p) //从此套接字发送数据报包。
  • void setBroadcast(boolean on) //启用/禁用 SO_BROADCAST。
  • static void setDatagramSocketImplFactory(DatagramSocketImplFactory fac) //设置工厂

实例应用——单线程

//服务端

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 {
        //1.创建DatagramSocket,指定端口号
        DatagramSocket socket = new DatagramSocket(6666);
        System.out.println("————服务器已启动————");
        byte[] data = new byte[1024];
        //2.创建DatagramPacket
        DatagramPacket packet = new DatagramPacket(data, data.length);
        //3.接收客户端发送的数据信息
        socket.receive(packet);
        //4.读取数据信息
        String info = new String(data, 0, packet.getLength());
        System.out.println("这里是服务器,客户端说:" + info);
        //5.定义发送信息
        InetAddress address = packet.getAddress();
        int port = packet.getPort();
        byte[] data2 = "欢迎使用".getBytes();
        //6.创建DatagramPakcet,包含要发送的信息
        DatagramPacket packet1 = new DatagramPacket(data2,data2.length,address,port);
        //7.发生数据
        socket.send(packet1);
        //8.关闭资源
        socket.close();
    }
}

//客户端 

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UDPClient {
    public static void main(String[] args) throws IOException {
        //1.定义发送信息
        InetAddress address = InetAddress.getByName("localhost");
        int port = 6666;
        byte[] data = "max:123".getBytes();
        //2.创建DatagramPacket,包含要发送的信息
        DatagramPacket packet = new DatagramPacket(data,data.length,address,port);
        //3.创建DatagramSocket
        DatagramSocket socket = new DatagramSocket();
        //4.发送数据
        socket.send(packet);
        byte[] data2 = new byte[1024];
        //5.创建DatagramPacket
        DatagramPacket packet1 = new DatagramPacket(data2,data2.length);
        //6.接受客户端发送的数据信息
        socket.receive(packet1);
        //7.读取数据
        String reply = new String(data2,0,packet1.getLength());
        System.out.println("这里是客户端,服务器说:"+reply);
        //8.关闭资源
        socket.close();
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_38500325/article/details/81410963