目录

1.套接字Socket

网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字。

1.1 构造函数

public Socket(InetAddress address,int port)创建一个流套接字并将其连接到指定 IP 地址的指定端口号。
public Socket(String host,int port)创建一个流套接字并将其连接到指定主机上的指定端口号。

1.2 方法

 public InputStream getInputStream()返回此套接字的输入流。可以用于接收网络消息
 public OutputStream getOutputStream()返回此套接字的输出流。可以用于发送网络消息
 public InetAddress getInetAddress()此套接字连接到的远程 IP 地址;如果套接字是未连接的,则返回 null。 
 public InetAddress getLocalAddress()获取套接字绑定的本地地址。 即本端的IP地址
 public int getPort()此套接字连接到的远程端口号;如果尚未连接套接字,则返回 0public int getLocalPort()返回此套接字绑定到的本地端口。 如果尚未绑定套接字,则返回 -1。即本端的端口号。 
 public void close()关闭此套接字。套接字被关闭后,便不可在以后的网络连接中使用(即无法重新连接或重新绑定)。需要创建新的套接字对象。 关闭此套接字也将会关闭该套接字的 InputStream 和OutputStream。 
 public void shutdownInput()如果在套接字上调用 shutdownInput() 后从套接字输入流读取内容,则流将返回 EOF(文件结束符)。 即不能在从此套接字的输入流中接收任何数据。
 public void shutdownOutput()禁用此套接字的输出流。对于 TCP 套接字,任何以前写入的数据都将被发送,并且后跟 TCP 的正常连接终止序列。 如果在套接字上调用 shutdownOutput() 后写入套接字输出流,则该流将抛出 IOException。 即不能通过此套接字的输出流发送任何数据。

1.3 IP地址

InetAddress address = InetAddress.getByName(String s);// 一般s是域名,例如www.baidu.com
InetAddress address = InetAddress.getLocalHost(); // 获取本地地址
address.getHostName();// 获取域名
address.getHostAddress()// 获取IP

2.TCP客户端和服务器传输数据的步骤

2.1 客户端Socket工作的四个基本步骤

  1. 创建 Socket:根据指定服务端的 IP 地址或端口号构造 Socket 类对象。若服务器端响应,则建立客户端到服务器的通信线路。若连接失败,会出现异常。
  2. 打开连接到 Socket 的输入/出流: 使用 getInputStream()方法获得输入流,使用getOutputStream()方法获得输出流,进行数据传输
  3. 按照一定的协议对 Socket 进行读/写操作:通过输入流读取服务器放入线路的信息(但不能读取自己放入线路的信息),通过输出流将信息写入线程。
  4. 关闭 Socket:断开客户端到服务器的连接,释放线路

2.2 服务器工作的四个基本步骤

  1. 调用 ServerSocket(int port) :创建一个服务器端套接字,并绑定到指定端口上。用于监听客户端的请求。
  2. 调用 accept():监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字对象。
  3. 调用 该Socket类对象的 getOutputStream() 和 getInputStream ():获取输出流和输入流,开始网络数据的发送和接收。
  4. 关闭ServerSocket和Socket对象:客户端访问结束,关闭通信套接字。

2.3 练习

从客户端发送文件给服务端,服务端保存到本地。并返回“发送成功”给客户端。并关闭相应的连接。

  1. 对于客户端和服务器之间的通信,必须使用Socket对象来获取输入或输出流。
  2. 客户端调用shutdownOutput()后,会在流的末尾写入一个结束标志,这样服务器才会读取到-1,跳出循环。

客户端:

    @Test
    public void test1() throws IOException {
//        1.创建客户端Socket对象,将服务端ip和端口号传入
        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 8899);
//        2.获取输出流和输入流,开始网络数据的发送和接收
        OutputStream outputStream = socket.getOutputStream();
//        3.传输文件
        FileInputStream fis = new FileInputStream("img.png");
        byte[] buffer = new byte[1024];
        int len;
        while ((len = fis.read(buffer)) != -1) {
            outputStream.write(buffer, 0, len);
        }
//      终止客户端输出,防止输出阻塞
        socket.shutdownOutput();
//      接受服务器回传的消息
        InputStream inputStream = socket.getInputStream();
        byte[] buffer1 = new byte[1024];
        while ((len = inputStream.read(buffer1)) != -1) {
            System.out.println(new String(buffer1,0,len));
        }
//        4.关闭资源
        outputStream.close();
        inputStream.close();
        fis.close();
        socket.close();
    }

服务器:

  public void test2() throws IOException {
//        1.创建一个服务器端套接字,并绑定到指定端口上。用于监听客户端的请求。
        ServerSocket ss = new ServerSocket(8899);
//        2.监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字对象
        Socket accept = ss.accept();
//        3.获取输出流和输入流,开始网络数据的发送和接收
        InputStream inputStream = accept.getInputStream();
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.png"));
        byte[] buffer = new byte[1024];
        int len;
        while ((len = inputStream.read(buffer)) != -1) {
            bos.write(buffer, 0, len);
        }
//        向客户端回传数据
        OutputStream outputStream = accept.getOutputStream();
        outputStream.write("发送成功".getBytes());
//        4.关闭资源
        inputStream.close();
        bos.close();
        outputStream.close();
        accept.close();
        ss.close();
    }

3.UDP通信

3.1 概述

UDP是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。如同发快递包裹一样。

3.2 通信流程

  1. 创建DatagramSocket对象,用于客户端和服务器间的通信;
  2. 创建DatagramPacket对象,用于存储数据;
  3. 客户端socket对象调用send()发送数据;
  4. 服务器socket对象调用receive()接收数据;
  5. 关闭socket服务;

3.3 应用实例

客户端:

    public void testClient() throws IOException {
        InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
        DatagramSocket socket = new DatagramSocket();
        String str = "hahahahah";
        byte[] bytes = str.getBytes();
//        指定服务器地址和端口
        DatagramPacket dp = new DatagramPacket(bytes,0,bytes.length,inetAddress,9090);
//        发送数据
        socket.send(dp);
        socket.close();
    }

服务器:

    public void testSever() throws IOException {
//        指定服务器端口
        DatagramSocket socket = new DatagramSocket(9090);
        byte[] buffer = new byte[1024];
        DatagramPacket dp = new DatagramPacket(buffer,0,buffer.length);
//        接收数据
        socket.receive(dp);
        System.out.println(new String(dp.getData(),0,dp.getLength()));
        socket.close();
    }

4.URL网络编程

4.1 URL的基本组成

https://www.bilibili.com/video/BV1Kb411W75N?p=629&spm_id_from=pageDriver
传输协议   域名				文件名				参数

4.2 方法

//public String getProtocol( ) 获取该URL的协议名
//public String getHost( ) 获取该URL的主机名
//public String getPort( ) 获取该URL的端口号
//public String getPath( ) 获取该URL的文件路径
//public String getFile( ) 获取该URL的文件名
//public String getQuery( ) 获取该URL的查询名(参数)

4.3 实例

public void testURL() throws MalformedURLException {
        URL url = new URL("https://www.bilibili.com/video/BV1Kb411W75N?p=629&spm_id_from=pageDriver");
        System.out.println(url.getProtocol());
        System.out.println(url.getHost());
        System.out.println(url.getPort());
        System.out.println(url.getPath());
        System.out.println(url.getFile());
        System.out.println(url.getQuery());
        //https
        //www.bilibili.com
        //-1
        ///video/BV1Kb411W75N
        ///video/BV1Kb411W75N?p=629&spm_id_from=pageDriver
        //p=629&spm_id_from=pageDriver
    }