1. IP地址

对于IPV4: 4个字节(32位)表示IP, 0—255
一个字节有8位,范围是:0—255
IP地址组成: 网络地址+主机地址: 192.168.16.69 192.168.16:69 北京市-海淀区—XX小区—房间号

ping www.baidu.com

image.png

ping www.taobao.com

image.png

2. 域名和端口

把IP地址映射成域名(HTTP协议)—-web
image.png
image.png

3. 网络通信协议

image.png

TCP: transmission control protocol
IP: internet protocol

image.png

4. 传输层:TCP/UDP

image.png

5. InetAddress类

5.1 继承关系图

image.png

5.2 代码演示

  1. import java.net.InetAddress;
  2. import java.net.UnknownHostException;
  3. public class InetAddressTest {
  4. public static void main(String[] args) throws UnknownHostException {
  5. // 1. 获取本地ip
  6. InetAddress localHost = InetAddress.getLocalHost();
  7. System.out.printf("localhost:%s", localHost); // localhost:DESKTOP-0F5TJ0D/192.168.1.10
  8. System.out.println();
  9. // 2. 通过指定主机名来获取ip
  10. InetAddress[] name = InetAddress.getAllByName("DESKTOP-0F5TJ0D");
  11. System.out.printf("通过主机名获取到的ip:%s", name[0]); // 通过主机名获取到的ip:DESKTOP-0F5TJ0D/192.168.1.10
  12. System.out.println();
  13. // 3. 根据域名返回InetAddress对象
  14. InetAddress byName = InetAddress.getByName("www.baidu.com");
  15. System.out.printf("通过域名获取ip:%s", byName); // 通过域名获取ip:www.baidu.com/182.61.200.6
  16. System.out.println();
  17. // 4. 通过InetAddress来反向获取对应的地址
  18. String hostAddress = byName.getHostAddress();
  19. System.out.printf(
  20. "通过InetAddress来反向获取对应的地址:%s", hostAddress); // 通过InetAddress来反向获取对应的地址:182.61.200.7
  21. }
  22. }

6. Socket

image.png

7. TCP字节流编程

image.png
1. 网络 - 图11

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketTCP01Server {
  public static void main(String[] args) throws IOException {
    /**
     * 1.在本机的9999端口监听,等待连接 2. 当没用客户端连接9999端口时,其进入等待状态 3. 通过socket.getInputStream()接收客户端写入到数据通道的数据
     */
    // 要求本地没用程序占用9999端口
    ServerSocket serverSocket = new ServerSocket(9999);
    System.out.println("服务端在9999端口监听,等待连接");
    // 如果有客户端连接,则会返回Socket对象,程序继续
    Socket accept = serverSocket.accept();
    System.out.printf("socket=%s", accept.getClass());
    System.out.println();
    InputStream inputStream = accept.getInputStream();
    byte[] bytes = new byte[1024];
    int readlen = 0;
    while ((readlen = inputStream.read(bytes)) != -1) {
      System.out.println(new String(bytes, 0, readlen));
    }
    // 关闭流和socket
    inputStream.close();
    accept.close();
    serverSocket.close();
  }
}

1. 网络 - 图12

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

public class SocketTCP01Client {
  public static void main(String[] args) throws IOException {
      /**
       * 1. 连接服务端(ip+port)
       * 2. 连接上后,生成Socket,通过socket.getOutputStream
       * 3. 通过输出流,写入数据到数据通道
       */
      // 连接本机的9999端口,如果连接成功,返回socket对象
      Socket client = new Socket(InetAddress.getLocalHost(), 9999);
    System.out.println("客户端显示的内容:"+client);
    // 得到socket对象关联的输出流对象
      OutputStream outputStream = client.getOutputStream();
      outputStream.write("hello!Server".getBytes());
    // 关闭流和对象
    System.out.println("输出完毕,客户端关闭!");
      outputStream.close();
      client.close();
  }
}

8. TCP字节流2

image.png
image.png
1. 网络 - 图15

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

@SuppressWarnings({"all"})
public class SocketTCP02Server {
  public static void main(String[] args) throws IOException {
    /**
     * 1.在本机的9999端口监听,等待连接 2. 当没用客户端连接9999端口时,其进入等待状态 3. 通过socket.getInputStream()接收客户端写入到数据通道的数据
     */
    // 要求本地没用程序占用9999端口
    ServerSocket serverSocket = new ServerSocket(9999);
    System.out.println("服务端在9999端口监听,等待连接");
    // 如果有客户端连接,则会返回Socket对象,程序继续
    Socket accept = serverSocket.accept();
    System.out.printf("socket=%s", accept.getClass());
    System.out.println();
    InputStream inputStream = accept.getInputStream();
    byte[] bytes = new byte[1024];
    int readlen = 0;
    while ((readlen = inputStream.read(bytes)) != -1) {
      System.out.println(new String(bytes, 0, readlen));
    }
    // 返回给客户端的内容
    OutputStream outputStream = accept.getOutputStream();
    outputStream.write("好的,服务器已收到你放的请求!".getBytes());
    accept.shutdownOutput();

    // 关闭流和socket
    System.out.println("消息发送完毕,服务器端关闭");
    outputStream.close();
    inputStream.close();
    accept.close();
    serverSocket.close();
  }
}

1. 网络 - 图16

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.sql.SQLOutput;

@SuppressWarnings({"all"})
public class SocketTCP02Client {
  public static void main(String[] args) throws IOException {
    /** 1. 连接服务端(ip+port) 2. 连接上后,生成Socket,通过socket.getOutputStream 3. 通过输出流,写入数据到数据通道 */
    // 连接本机的9999端口,如果连接成功,返回socket对象
    Socket client = new Socket(InetAddress.getLocalHost(), 9999);
    System.out.println("客户端显示的内容:" + client);
    // 得到socket对象关联的输出流对象
    OutputStream outputStream = client.getOutputStream();
    outputStream.write("hello!Server".getBytes());
    client.shutdownOutput();

    // 读取服务器返回的内容
    InputStream inputStream = client.getInputStream();
    byte[] bytes = new byte[1024];
    int readlen = 0;
    if ((readlen = inputStream.read(bytes)) != -1) {
      System.out.println("客户端接收服务器返回的内容:");
      System.out.println(new String(bytes, 0, readlen));
    }

    // 关闭流
    // 关闭流和对象
    System.out.println("输出完毕,客户端关闭!");
    inputStream.close();
    outputStream.close();
    client.close();
  }
}

9. 字符流通信

image.png
image.png
1. 网络 - 图19

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

@SuppressWarnings({"all"})
public class SocketTCP03Server {
  public static void main(String[] args) throws IOException {
    /**
     * 1.在本机的9999端口监听,等待连接 2. 当没用客户端连接9999端口时,其进入等待状态 3. 通过socket.getInputStream()接收客户端写入到数据通道的数据
     */
    // 要求本地没用程序占用9999端口
    ServerSocket serverSocket = new ServerSocket(9999);
    System.out.println("服务端在9999端口监听,等待连接");
    // 如果有客户端连接,则会返回Socket对象,程序继续
    Socket accept = serverSocket.accept();
    System.out.printf("socket=%s", accept.getClass());
    System.out.println();
    InputStream inputStream = accept.getInputStream();
    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
    String readLine = bufferedReader.readLine();
    System.out.println("服务端读取到了内容:"+readLine);

    // 返回给客户端的内容
    System.out.println("以下是服务器对客户端的回复:");
    OutputStream outputStream = accept.getOutputStream();
    BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
    bufferedWriter.write("客户端你好,我是服务器。接下来你需要这么做。。。。");
    bufferedWriter.newLine();
    bufferedWriter.flush();


    // 关闭流和socket
    System.out.println("消息发送完毕,服务器端关闭");
    bufferedWriter.close();
    bufferedReader.close();
    accept.close();
    serverSocket.close();
  }
}
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;

@SuppressWarnings({"all"})
public class SocketTCP03Client {
  public static void main(String[] args) throws IOException {
    /** 1. 连接服务端(ip+port) 2. 连接上后,生成Socket,通过socket.getOutputStream 3. 通过输出流,写入数据到数据通道 */
    // 连接本机的9999端口,如果连接成功,返回socket对象
    Socket client = new Socket(InetAddress.getLocalHost(), 9999);
    System.out.println("客户端显示的内容:" + client);
    // 得到socket对象关联的输出流对象
    OutputStream outputStream = client.getOutputStream();
    BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
    bufferedWriter.write("服务器你好,我是客户XXX");
    bufferedWriter.newLine(); // 结束写入的标记
    bufferedWriter.flush(); // 刷进数据管道中

    // 读取服务器返回的内容
    InputStream inputStream = client.getInputStream();
    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
    String readLine = reader.readLine();
    System.out.println(readLine);

    // 关闭流
    // 关闭流和对象
    System.out.println("输出完毕,客户端关闭!");
    reader.close();
    bufferedWriter.close();
    client.close();
  }
}

10. 网络上传文件

image.png
image.png

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

public class TCPFileuploaderService {
  public static void main(String[] args) throws IOException {
      // 服务器端
      ServerSocket serverSocket = new ServerSocket(8888);
    System.out.println("服务端咋");
      Socket socket = serverSocket.accept();

    // 读取客户端发送的数据
      InputStream inputStream = socket.getInputStream();
      BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
      byte[] bytes = StreamUtil.streamToByteArray(bufferedInputStream);
      // 将得到的bytes写入到指定的路径,就得到了一个文件了
      String destFilePath = "e:\\zhao2.jpg";
      BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(destFilePath));
      bufferedOutputStream.write(bytes);

      // 关闭其他资源
      bufferedInputStream.close();
      socket.close();
      serverSocket.close();

  }
}
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

public class TCPuploadFile {
  public static void main(String[] args) throws IOException {
      //客户端尝试连接服务器
      Socket socket = new Socket(InetAddress.getLocalHost(), 8888);

      // 读取磁盘文件
      String filepath ="e:\\zhao.jpg";
      BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(filepath));
      // bytes就是filepath中文件对应的字节数组
      byte[] bytes = StreamUtil.streamToByteArray(bufferedInputStream);

      // 通过socket获取到输出流,将bytes传入到数据管道中
      BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(socket.getOutputStream());
      bufferedOutputStream.write(bytes);
      bufferedInputStream.close();
      socket.shutdownOutput();// 设置写入数据的结束标记
      bufferedOutputStream.close();
      socket.close();
  }
}



class StreamUtil{
  public static byte[] streamToByteArray(InputStream is) throws IOException {
      ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
      byte[] bytes = new byte[1024];
      int len;
      while((len=is.read(bytes))!=-1){
          byteArrayOutputStream.write(bytes, 0, len);
      }
      byte[] byteArray = byteArrayOutputStream.toByteArray();
      byteArrayOutputStream.close();
      return byteArray;
  }

}

11. netstat

netstat —an | more

12. UDP

数据发送和接收是通过 datagramPacket对象来完成的

image.png
image.png

import java.io.IOException;
import java.net.*;

public class UDPsender {
  public static void main(String[] args) throws IOException {
      DatagramSocket socket = new DatagramSocket(9998);
      // 将需要发送的数据,封装到datagramPacket中
      byte[] data = "hotpork,tomorrow".getBytes();
      DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getLocalHost(), 9999);

      socket.send(packet);
      socket.close();

  }
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class UDPReceiver {
  public static void main(String[] args) throws IOException {
    DatagramSocket socket = new DatagramSocket(9999);
    byte[] bytes = new byte[1024];
    DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
    // 将通过网络传输的数据封装到packet中
    // 当有数据报发送到9999端口时,就会自动接收。如果没有,就会等待、阻塞
    socket.receive(datagramPacket);

    // 拆包
    int length = datagramPacket.getLength();
    byte[] data = datagramPacket.getData(); // 接收到数据

    String s = new String(data, data.length);
    System.out.println(s);
    socket.close();
  }
}