网络的基本概念

  • 连接多台电脑之间的通信的方式就是网络
  • 实现网路通信要指定协议,网络协议中最基础的协议就是网络七层架构协议

    • 底层协议
      • 物理层:用于网络的链接
      • 数据链路层:用于数据的交互
      • 网络层:路由器,主要用于寻址
    • 应用层协议
      • 传输层,主要使用TCP/IP协议进行数据的传递
      • 会话层:主要实现两个终端的会话
      • 表示层:主要实现两个通信终端之间的编码格式的转换
      • 应用层:提供了各种通信协议,FTP(文件传递协议),POP3(邮箱协议),Http(超文本传送协议)

        TCP/IP协议

  • tcp/ip协议提出一个ip地址的概念,ip地址就是电脑在网络中的唯一标识

    • 在window使用使用ipconfig能查看本机的ip地址
    • 可以通过ping验证两台电脑之间网络是否通畅
    • ipv4和ipv6

      • ipv4地址 :::info 255.255.255.255 :::

      • ipv6 :::info FFFF.FFFF.FFFF.FFFF.FFFF.FFFF.FFFF.FFFF :::

  • 域名的概念

    • ip地址比较容易记,那么就提出了域名的概念
    • 域名本质上是在DNS服务上和IP地址绑定的字符串
  • 端口的概念

    • 端口是一台电脑的进程的唯一的标识
    • 也就是说一台电脑程序要连接另一台电脑上的程序必须要通过地址+端口

      基于TCP/IP协议常用类

  • InetAddress类,java对IP信息的封装 ```java

    1. InetAddress localHost = InetAddress.getLocalHost(); //本机
  1. System.out.println("本机IP地址:" + localHost.getHostAddress());
  2. System.out.println("本机名称:" + localHost.getHostName());
  3. //根据域名得到InetAddress对象
  4. InetAddress bd = InetAddress.getByName("www.baidu.com");
  5. System.out.println("百度服务器地址:" + bd.getHostAddress());
  6. System.out.println("百度服务器名称:" + bd.getHostName());
  7. //根据IP地址得到InetAddress对象
  8. InetAddress ia = InetAddress.getByName("39.130.131.42");
  9. System.out.println("服务器主机IP:" + ia.getHostAddress());
  10. //如果39.130.131.42IP地址不存在或者DNS(域名解析系统)不允许进行IP地址和域名的映射,就会直接返回域名地址
  11. System.out.println("主机名称" + ia.getHostName());
  1. - <br />
  2. - InetSocketAddress :主要用实现IP和端口的数据的存储
  3. ```java
  4. //创建对象
  5. InetSocketAddress is1 = new InetSocketAddress("localhost", 9999);
  6. InetSocketAddress is2 = new InetSocketAddress("127.0.0.1", 9999);
  7. InetSocketAddress is3 = new InetSocketAddress("192.168.136.1", 9999);
  8. InetAddress ia = InetAddress.getByName("192.168.136.1");
  9. InetSocketAddress is4 = new InetSocketAddress(ia, 9999);
  10. System.out.println("主机名称:" + is4.getHostName());
  11. System.out.println("主机IP地址:" + is4.getAddress());

Socket编程

  • 建立服务器和客户端之间的连接
    • 创建服务器 ```java public static void main(String[] args) throws IOException { //创建服务器,指定端口号,默认绑定本机地址 ServerSocket serverSocket = new ServerSocket(8888); System.out.println(“创建了服务器”); //当前服务器等待其他的客户端进行链接 serverSocket.accept();//会阻塞代码 System.out.println(“有人进来了”); }
  1. - 创建客户端,并且连接服务器
  2. ```java
  3. public static void main(String[] args) throws IOException {
  4. //第一个参数是主机的ip,是字符串类型
  5. //127.0.0.1 默认是本机的端口号
  6. //localhost 默认是本机的域名
  7. //第二个参数是端口是int类型
  8. Socket socket = new Socket("localhost",8888);
  9. System.out.println("连接服务器");
  10. }
  • 单向通信

    • 实现服务器代码

      1. //服务器
      2. public class Server {
      3. public static void main(String[] args) throws IOException {
      4. //创建服务器,指定端口号,默认绑定本机地址
      5. ServerSocket serverSocket = new ServerSocket(8888);
      6. System.out.println("创建了服务器");
      7. //当前服务器等待其他的客户端进行链接
      8. Socket socket = serverSocket.accept();//会阻塞代码
      9. System.out.println("有人进来了");
      10. //通过一个socket打开一个输入流
      11. InputStream inputStream = socket.getInputStream();
      12. //创建数据
      13. DataInputStream dis = new DataInputStream(inputStream);
      14. String msg = dis.readUTF();//读取string数据
      15. System.out.println("收到来自客户端的消息:"+msg);
      16. }
      17. }
    • 实现客户端代码

      1. //客户端代码
      2. public class Client {
      3. public static void main(String[] args) throws IOException {
      4. //第一个参数是主机的ip,是字符串类型
      5. //127.0.0.1 默认是本机的端口号
      6. //localhost 默认是本机的域名
      7. //第二个参数是端口是int类型
      8. Socket socket = new Socket("localhost",8888);
      9. System.out.println("连接服务器");
      10. //通过socket获取输出流
      11. OutputStream os = socket.getOutputStream();
      12. DataOutputStream dos = new DataOutputStream(os);
      13. //在控制台输入内容
      14. Scanner scanner = new Scanner(System.in);
      15. dos.writeUTF(scanner.next());
      16. System.out.println("消息发送成功");
      17. os.close();
      18. }
      19. }
  • 双向通信

    • 服务器端,先accpet接收客户端,再接收来自客户端的消息,最后返回消息给客户端

      1. public static void main(String[] args) throws IOException {
      2. //创建服务器,指定端口号,默认绑定本机地址
      3. ServerSocket serverSocket = new ServerSocket(8888);
      4. System.out.println("创建了服务器");
      5. //当前服务器等待其他的客户端进行链接
      6. Socket socket = serverSocket.accept();//会阻塞代码
      7. System.out.println("有人进来了");
      8. ////////////////////读取数据
      9. //通过一个socket打开一个输入流
      10. InputStream inputStream = socket.getInputStream();
      11. //创建数据
      12. DataInputStream dis = new DataInputStream(inputStream);
      13. String msg = dis.readUTF();//读取string数据
      14. System.out.println("收到来自客户端的消息:"+msg);
      15. ////////////////////输出数据
      16. //服务器端返回消息
      17. OutputStream os = socket.getOutputStream();
      18. DataOutputStream dos = new DataOutputStream(os);
      19. Scanner scanner = new Scanner(System.in);
      20. dos.writeUTF(scanner.next());
      21. }
    • 客户端,连接服务器段,发送消息,最后接收来服务器端的消息 ```java public static void main(String[] args) throws IOException { //第一个参数是主机的ip,是字符串类型 //127.0.0.1 默认是本机的端口号 //localhost 默认是本机的域名 //第二个参数是端口是int类型 Socket socket = new Socket(“localhost”,8888); System.out.println(“连接服务器”);

      //////////////////输出数据 //通过socket获取输出流 OutputStream os = socket.getOutputStream(); DataOutputStream dos = new DataOutputStream(os); //在控制台输入内容 Scanner scanner = new Scanner(System.in); dos.writeUTF(scanner.next());//会阻塞代码 System.out.println(“消息发送成功”);

  1. ///////////////////////////////
  2. /////////读取数据
  3. InputStream in = socket.getInputStream();
  4. DataInputStream dis = new DataInputStream(in);
  5. String result = dis.readUTF(); //会阻塞代码
  6. System.out.println("来自服务器的消息:"+result);
  7. }
  1. - 通过线程实现两者可以随意通信
  2. - 服务器端代码
  3. ```java
  4. public class Server {
  5. public static void main(String[] args) throws IOException {
  6. //创建服务器,指定端口号,默认绑定本机地址
  7. ServerSocket serverSocket = new ServerSocket(8888);
  8. System.out.println("创建了服务器");
  9. //当前服务器等待其他的客户端进行链接
  10. Socket socket = serverSocket.accept();//会阻塞代码
  11. System.out.println("有人进来了");
  12. ////////////////////读取数据
  13. //通过一个socket打开一个输入流
  14. //创建一个线程用户接收数据
  15. Thread thread = new Thread(){
  16. @Override
  17. public void run() {
  18. while (true){
  19. InputStream inputStream = null;
  20. try {
  21. inputStream = socket.getInputStream();
  22. //创建数据
  23. DataInputStream dis = new DataInputStream(inputStream);
  24. String msg = dis.readUTF();//读取string数据
  25. System.out.println("客户端说:"+msg);
  26. } catch (IOException e) {
  27. e.printStackTrace();
  28. }
  29. }
  30. }
  31. };
  32. thread.start();
  33. while(true){
  34. ////////////////////输出数据
  35. //服务器端返回消息
  36. OutputStream os = socket.getOutputStream();
  37. DataOutputStream dos = new DataOutputStream(os);
  38. Scanner scanner = new Scanner(System.in);
  39. dos.writeUTF(scanner.next());
  40. System.out.println("发送消息成功");
  41. }
  42. }
  43. }
  • 客户端代码

    1. //客户端代码
    2. public class Client {
    3. public static void main(String[] args) throws IOException {
    4. //第一个参数是主机的ip,是字符串类型
    5. //127.0.0.1 默认是本机的端口号
    6. //localhost 默认是本机的域名
    7. //第二个参数是端口是int类型
    8. Socket socket = new Socket("localhost",8888);
    9. System.out.println("连接服务器");
    10. ///////////////////////////////
    11. /////////读取数据
    12. Thread thread = new Thread(){
    13. @Override
    14. public void run() {
    15. while(true){
    16. InputStream in = null;
    17. try {
    18. in = socket.getInputStream();
    19. DataInputStream dis = new DataInputStream(in);
    20. String result = dis.readUTF(); //会阻塞代码
    21. System.out.println("服务器说:"+result);
    22. } catch (IOException e) {
    23. e.printStackTrace();
    24. }
    25. }
    26. }
    27. };
    28. thread.start();
    29. while(true){
    30. //////////////////输出数据
    31. //通过socket获取输出流
    32. OutputStream os = socket.getOutputStream();
    33. DataOutputStream dos = new DataOutputStream(os);
    34. //在控制台输入内容
    35. Scanner scanner = new Scanner(System.in);
    36. dos.writeUTF(scanner.next());//会阻塞代码
    37. System.out.println("消息发送成功");
    38. }
    39. }
    40. }

    UDP通信

  • TCP(Transmission Control Protocol )传输控制协议是一种面向连接的、可靠的、基于字节流的传输层通信协议。数据大小无限制。建立连接的过程需要三次握手,断开连接的过程需要四次挥手。不会出现丢包的问题,但是速度相对慢
  • UDP(User Datagram Protocol) 用户数据报协议:是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,每个包的大小64KB。会出现丢包的问题,但是速度快
  • UDP服务器端

    1. public static void main(String[] args) throws IOException {
    2. //创建一个udp的socket
    3. DatagramSocket server = new DatagramSocket(7777);
    4. System.out.println("udp服务器在7777端口启动");
    5. //2有一个空的数据包(缓存),打算用了来接收对方传过来带的数据库包
    6. DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);
    7. //接收消息
    8. server.receive(packet); //也会阻塞线程
    9. //直接packet从获取数据
    10. byte[] data = packet.getData();
    11. int len = packet.getLength(); //获取数据的长度
    12. System.out.println("接收的数据:"+new String(data,0,len));
    13. //4,关闭资源
    14. server.close();
    15. }
  • UPD客户端

    1. public static void main(String[] args) throws IOException {
    2. //创建客户端的socket
    3. DatagramSocket client = new DatagramSocket(6666);
    4. System.out.println("客户端在6666端口启动了");
    5. Scanner scanner = new Scanner(System.in);
    6. String msg = scanner.next();
    7. byte[] data = msg.getBytes(StandardCharsets.UTF_8);
    8. DatagramPacket datagramPacket = new DatagramPacket(
    9. data,//发送的数据
    10. data.length,//发送数据的长度
    11. InetAddress.getByName("localhost"),
    12. 7777
    13. );
    14. client.send(datagramPacket);
    15. System.out.println("发送请求成功");
    16. client.close();
    17. }

    Http通信

  • Http属于一种无状态连接

    • socket可以双向通信,连接是一致保存的
    • http是单项通信,只能是客户端发送请求给服务器端,然后服务器端再返回请求可客户端。连接就结束了
      • 服务器端不可以主动发请求给客户端
  • http协议的组成
    • 两个部分
      • 头部
      • 正文
    • 两个环节
      • 请求
      • 响应
  • 基于http协议的编程

    • 服务器端不需要自己创建,已经有很成熟的http服务器,例如tomcat
    • 在java中发送http请求

      1. //1,创建一个url对象用于存储发送请求的地址
      2. URL url = new URL("http://www.baidu.com");
      3. //2,打开连接
      4. HttpURLConnection connection = (HttpURLConnection) url.openConnection();
      5. //3,设置请求方式GET POST PUT DELETE
      6. connection.setRequestMethod("GET");
      7. //4,连接服务器
      8. connection.connect();
      9. //5,获取响应结果
      10. InputStream in = connection.getInputStream();
      11. //创建缓存流
      12. BufferedReader br = new BufferedReader(new InputStreamReader(in));
      13. String line;
      14. StringBuilder sb = new StringBuilder();
      15. while((line=br.readLine())!=null){
      16. sb.append(line);
      17. }
      18. System.out.println(sb.toString());
      19. br.close();
      20. in.close();