网络编程(Network)

声明:以下笔记来源于韩顺平视频https://www.bilibili.com/video/BV1fh411y7R8?p=1,笔记为楼主亲手劳动,劳动不易,转载请标明谢谢。

网络编程

IP 地址
  1. 概念:用于唯一标识网络中的每台计算机/主机
  2. 查看ip地址: ipconfig
  3. ip地址的表示形式:点分十进制xx.xx.xx.xx
  4. 每一个十进制数的范围: 0~255
  5. ip地址的组成=网络地址+主机地址,比如: 192.168.16.69
  6. iPv6是互联网工程任务组设计的用于替代IPv4的下一代IP协议,其地址数量号称可以为全世界的每一 粒沙子编上一 个地址。
  7. 由于IPv4最大的问题在于网络地址资源有限,严重制约了互联网的应用和发展。IPv6的使用,不仅能解决网络地址资源数量的问题,而且也解决了多种接入设备连入互联网的障碍
域名
  1. www.baidu.com
  2. 好处:为了方便记忆,解决记ip的困难
  3. 概念:将ip地址映射成域名,这里怎么映射上,HTTP协议
端口
  1. 概念:用于标识计算机上某个特定的网络程序

  2. 表示形式:以整数形式,端口范围O~ 65535 [2个字节表示端口0~2^16-1]

  3. 0~1024已经被占用,比如ssh 22, ftp 21, smtp 25 http 80

  4. 常见的网络程序端口号:

    1. tomcat :8080
    2. mysql:3306
    3. oracle:1521
    4. sqlserver:1433
  5. 在网络开发中,不要使用0-1024 的端口名花有主。

网络通信协议

TCP/IP (Transmission ControlProtocol/Internet Protocol)的简写,中文译名为传输控制协议/因特网互联协议,又叫网络通讯协议,这个协议是Internet最基本的协议、Internet国际互联网络的基础,简单地说,就是由网络层的IP协议和传输层的TCP协议组成的。

OSI 模型TCP/IP模型TCP/IP模型各层对应的协议
应用层应用层HTTP//telnet/ftp/DNS
表示层应用层HTTP//telnet/ftp/DNS
会话层应用层HTTP//telnet/ftp/DNS
传输层传输层TCP/UDP/
网络层网络层IP/ICMP/ARP
数据链路层物理+ 数据链路层Link
物理层物理+ 数据链路层Link
TCP 与 UTP
  1. TCP 协议:

      1. 使用TCP协议前,须先建立TCP连接,形成传输数据通道
      2. 传输前,采用"三次握手"方式,是可靠的
      3. TCP协议进行通信的两个应用进程:客户端、服务端
      4. 在连接中可进行大数据量的传输
      5. 传输完毕,需释放已建立的连接,效率低
  2. UTP 协议:

      1. 将数据、源、目的封装成数据包,不需要建立连接
      2. 每个数据报的大小限制在64K内,不适合传输大量数据
      3. 因无需连接,故是不可靠的
      4. 发送数据结束时无需释放资源(因为不是面向连接的),速度快
InetAddress
  1. 获取本机InetAddress对象getLocalHost

  2. 根据指定主机名/域名获取ip地址对象getByName

  3. 获取InetAddress对象的主机名getHostName

  4. 获取InetAddress对象的地址getHostAddress

  5. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DYq1R9Z7-1648481617034)(D:/Typora%20Data/Img/image-20220320155146386.png)]

  6. public class Api_ {
    public static void main(String[] args) throws UnknownHostException {
    
      InetAddress host = InetAddress.getLocalHost();
      System.out.println(host);//LAPTOP-OGEO85S7/192.168.179.1
    
      InetAddress host1 = InetAddress.getByName("LAPTOP-OGEO85S7");
      System.out.println(host1);//LAPTOP-OGEO85S7/192.168.179.1
    
      InetAddress host1 = InetAddress.getByName("192.168.179.1");
      System.out.println(host1);//LAPTOP-OGEO85S7/192.168.179.1
    
      InetAddress host2 = InetAddress.getByName("www.baidu.com");
      System.out.println(host2);//www.baidu.com/14.215.177.38
    
      System.out.println(host2.getHostAddress());//14.215.177.38
    
      System.out.println(host2.getHostName());//www.baidu.com
    }
    }
    
Socket
  1. 套接字(Socket)开发网络应用程序被广泛采用,以至于成为事实上的标准。
  2. 通信的两端都要有Socket,是两台机器间通信的端点
  3. 网络通信其实就是Socket间的通信。
  4. Socket允许程序把网络连接当成一个流, 数据在两个Socket间通过IO传输。
  5. 一般主动发起通信的应用程序属客户端,等待通信请求的为服务端
TCP 网络通信编程
  1. 基于客户端一服务端的网络通信

  2. 底层使用的是TCP/IP协议

  3. 应用场景举例:客户端发送数据,服务端接受并显示控制台

  4. 基于Socket的TCP编程

  5. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xl448Evz-1648481617040)(D:/Typora%20Data/Img/image-20220320160241153.png)]

  6. 案例1 字节流

        1. 编写一个服务器端,和一个客户端
        2. 服务器端在9999端口监听
        3. 客户端连接到服务器端,发送"hello, server" ,并接收服务器端会送的"hello,client",然后退出
        4. 服务器端接收到客户端发送的信息,输出,并发送"hello,client",并退出
      1. public class SocketTCP01Client {
         public static void main(String[] args) throws IOException {
             Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
             OutputStream os = socket.getOutputStream();
             os.write("hello,world".getBytes());
             socket.shutdownOutput();//设置结束标记,尤为重要
             byte[] buf = new byte[1024];
             int readlen = 0;
             InputStream is = socket.getInputStream();
             while ((readlen = is.read(buf)) != -1) {
                 System.out.println(new String(buf,0,readlen));
             }
             is.close();
             os.close();
             socket.close();
         }
        }
        
        
        public class SocketTCP01Server {
         public static void main(String[] args) throws IOException {
             ServerSocket serverSocket = new ServerSocket(9999);
             Socket socket = serverSocket.accept();
             InputStream is = socket.getInputStream();
             byte[] buf = new byte[1024];
             int readlen = 0;
             while ((readlen = is.read(buf)) != -1) {
                 System.out.println(new String(buf,0,readlen));
             }
             OutputStream os = socket.getOutputStream();
             os.write("hello,client".getBytes());
             socket.shutdownOutput();//设置结束标记,尤为重要
             os.close();
             is.close();
             socket.close();
             serverSocket.close();
         }
        }
        
        
  7. 案例2 字符流

    • @SuppressWarnings({"all"})
      public class SocketTCP02Server {
       public static void main(String[] args) throws IOException {
           ServerSocket serverSocket = new ServerSocket(9999);
           Socket socket = serverSocket.accept();
      
           InputStream is = socket.getInputStream();
           BufferedReader bufR = new BufferedReader(new InputStreamReader(is));
           String readlen = bufR.readLine();
           System.out.println(readlen);
      
           OutputStream os = socket.getOutputStream();
           BufferedWriter bufW = new BufferedWriter(new OutputStreamWriter(os));
           bufW.write("hello,client 字符流");
           bufW.newLine();//如果用newLine表示结束换行,对方的读入要用readLine才能读到
           bufW.flush();//真正写入通道
      
      
           bufW.close();
           bufR.close();
           socket.close();
           serverSocket.close();
       }
      }
      
      @SuppressWarnings({"all"})
      public class SocketTCP02Client {
       public static void main(String[] args) throws IOException {
           Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
           OutputStream os = socket.getOutputStream();
           BufferedWriter bufW = new BufferedWriter(new OutputStreamWriter(os));
           bufW.write("hello,server 字符流");
           bufW.newLine();//表示换行结束十分重要
           bufW.flush();//表示真正写入通道,十分重要
      
      
           InputStream is = socket.getInputStream();
           BufferedReader bufR = new BufferedReader(new InputStreamReader(is));
           String readLine = bufR.readLine();
           System.out.println(readLine);
      
           bufR.close();
           bufW.close();
           socket.close();
       }
      }
      
网络上传文件案例
  1. 要求

      1. 编写一个服务端,和一个客户端
      2. 服务器端在8888端口监听
      3. 客户端连接到服务端,发送一张图片e:\qie.png
      4. 服务器端接收到客户端发送的图片,保存到src下,发送"收到图片”再退出
      5. 客户端接收到服务端发送的"收到图片",再退出
      6. 该程序要求使用StreamUtils.java,我们直接使用
  2. 实现

    • public class TCPFileUploadServer {
       public static void main(String[] args) throws Exception {
           ServerSocket serverSocket = new ServerSocket(9999);
           Socket socket = serverSocket.accept();
      
           BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
           byte[] bytes = StreamUtils.streamToByteArray(bis);
      
           String filePath = "d:\\test\\meinv.jpg";
           BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath));
           bos.write(bytes);
      
           BufferedWriter bufW = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
           bufW.write("收到图片");
           bufW.flush();
           socket.shutdownOutput();
      
           bufW.close();
           bos.close();
           bis.close();
           socket.close();
           serverSocket.close();
       }
      }
      
      public class TCPFileUploadClient {
       public static void main(String[] args) throws Exception {
           Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
      
           String filePath = "c:\\test\\meinv.jpg";
           BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath));
      
           byte[] bytes = StreamUtils.streamToByteArray(bis);
           BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
           bos.write(bytes);
           socket.shutdownOutput();
      
           InputStream is = socket.getInputStream();
           String mes = StreamUtils.streamToString(is);
           System.out.println(mes);
      
           is.close();
           bos.close();
           bis.close();
           socket.close();
       }
      }
      
netstat 指令
  1. netstat -an可以查看当前主机网络情况,包括端口监听情况和网络连接情况
    1. netstat -an | more可以分页显示,空格表示下一页,回车表示下一行
  2. 要求在dos控制台下执行win+r
  3. Listening表示某个端口在监听
  4. 如果有一个外部程序(客户端)连接到该端口,就会显示条连接信息.
  5. 可以输入ctrI + C退出指令
  6. netstat -anb 可以查看其占用端口的应用程序
UTP 网络通信编程
  1. 类DatagramSocket和DatagramPacket[数据包/数据报]实现了基于UDP协议网络程序。

  2. UDP数据报通过数据报套接字DatagramSocket发送和接收,系统不保证UDP数据报一定能够安全送到目的地,也不能确定什么时候可以抵达。

  3. DatagramPacket对象封装了UDP数据报,在数据报中包含了发送端的IP地址和端口号以及接收端的IP地址和端口号

  4. UDP协议中每个数据报都给出了完整的地址信息,因此无须建立发送方和接收方的连接

  5. 基本流程

      1. 核心的两个类/对象DatagramSocket与DatagramPacket
      2. 建立发送端,接收端
      3. 建立数据包
      4. 调用DatagramSocket的发送、接收方法
      5. 关闭DatagramSocket
  6. 细节说明

      1. 没有明确的服务端和客户端,演变成数据的发送端和接收端
      2. 接收数据和发送数据是通过DatagramSocket对象完成
      3. 将数据封装到DatagramPacket对象/装包
      4. 当接收到DatagramPacket对象,需要进行拆包,取出数据
      5. DatagramSocket 可以指定在哪个端口接收数据
  7. 练习题

      1. 编写一个接收端A,和一个发送端B
      2. 接收端A在9999端口等待接收数据(receive)
      3. 发送端B向接收端A发送数据"hello ,明天吃火锅~’
      4. 接收端B接收到发送端A发送的数据,回复 “好的,明天见”,再退出
      5. 发送端接收回复的数据,再退出
    • public class UDPReceiverA {
       public static void main(String[] args) throws IOException {
           DatagramSocket socket = new DatagramSocket(9999);
           byte[] buf = new byte[1024];//一般UTP报文最大长度是64k,就是 64 * 1024,这里不需要这么多
           DatagramPacket packet = new DatagramPacket(buf, buf.length);
           socket.receive(packet);
           int length = packet.getLength();
           byte[] data = packet.getData();
           System.out.println(new String(data, 0, length));
      
           byte[] bytes = "好的,明天见~".getBytes();
           packet = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("172.20.151.168"), 9998);
           System.out.println("UDPReceiverA 发送 好的,明天见~ 给 UDPSenderB");
           socket.send(packet);
      
      
           socket.close();
       }
      }
      
      public class UDPSenderB {
       public static void main(String[] args) throws IOException {
           DatagramSocket socket = new DatagramSocket(9998);
           byte[] bytes = "hello,明天吃火锅".getBytes();
           DatagramPacket packet = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("172.20.151.168"), 9999);
           System.out.println("UDPSenderB发送hello,明天吃火锅给UDPReceiverA");
           socket.send(packet);
      
      
           byte[] buf = new byte[1024];//一般UTP报文最大长度是64k,就是 64 * 1024,这里不需要这么多
           packet = new DatagramPacket(buf, buf.length);
           socket.receive(packet);
           int length = packet.getLength();
           byte[] data = packet.getData();
           System.out.println(new String(data, 0, length));
      
           socket.close();
       }
      }
      
项目开发流程
  1. 需求分析

  2. 设计阶段

  3. 编码实现

  4. 测试阶段

  5. 实施阶段

  6. 维护阶段

  7. [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0AEPbysk-1648481617042)(D:/Typora%20Data/Img/image-20220322154231568.png)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值