网络编程学习笔记❤️

网络编程

1.1、概述:

计算机网络

  • 是指将地理位置不同的具有 独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。

网络编程:

  • 在网络通信协议下,实现网络互连的不同计算机上运行的程序间可以进行数据交换

网络编程的目的:

  • 传播交流信息,数据交换,通信。

想要达到这个效果需要什么:

  1. 如何准确的定位网络上的一台主机端口,定位到这个计算机上的某个资源。
  2. 找到了这个主机,该如何传输数据?

javaweb: 网页编程 B/S

网络编程: TCP/IP C/S

1.2、网络通信的要素

  • 规则:网络通信的协议

    TCP/IP参考模型:

    OSI中的层功能TCP/IP协议族
    应用层文件传输、电子邮件、文件服务、虚拟终端TFTP、HTTP、SNNP、FTP、SMTP、DNS、Telnet
    表示层数据格式化、代码转换、数据加密没有协议
    会话层解除或建立与别的接点的联系没有协议
    传输层提供端对端的接口TCP、UDP
    网络层为数据包选择路由IP、ICMP、RIP、OSPF、BGP、ICMP
    数据链路层传输有地址的帧以及错误检测功能SLIP、CSLIP、PPP、ARP、RARP、MTU
    物理层以二进制数据形式在物理媒体上传输数据ISO2110、IEEE802、IEEE802.2
  • 网络编程中的要素

    1. IP和端口号
    2. 网络通信协议
  • 网络编程中两个主要的问题

    1. 如何准确的定位到网络上的一台或者多台主机
    2. 找到主机之后如何进行通信

1.2.1、 IP地址

  • 定义:

    要想让网络中的计算机能够互相通信,必须为每台计算机指定一个标识号,通过这个标识号来指定接收数据的计算机和识别发送的计算机,而IP地址就是这个标识号,也就是设备的标识。

  • ip地址操作类:IntAddress

    • InetAddress类概述:
      一个该类的对象就代表一个IP地址对象。
    • InetAddress类成员方法:
      static InetAddress getLocalHost()
  • 127.0.0.1:本机localhost

  • IP地址分类

    • IPv4/IPv6

      • IPV4 : 127.0.0.1 , 4个字节组成 , 0~255, 总共42亿;30亿都在北美,亚洲只有4亿。2011年用尽 ,IPV4是给每个连接在网络上的主机分配一个32bit地址。 按照TCP/IP规定,IP地址用二进制来表示,每个IP地址长32bit,也就是4个字节。例如一个采用二进制形式的IP地址是 “1100000 1010100 00000001 01000010* , 这么长的地址,处理起来也太费劲了。为了方便使用,IP地址经常被写成十进制的形式,中间使用符号".“分隔不同的字节。于是,上面的IP地址可以表示为 “192.168.1.66” 。IP地址的这种表示法叫做“点分十进制表示法”,这显然比1和0容易记忆得多。

      • IPV6:由于互联网的蓬勃发展, IP地址的需求量愈来愈大,但是网络地址资源有限,使得IP的分配越发紧张。为了扩大地址空间,通过IPv6重新定义地址空间,采用128位地址长度,每16个字节一组, 分成8组十六进制数,这样就解决了网络地址资源数量不够的问题

        如( fe80::fc35:361d:cf06:30a0%20),128位,8个无符号整数构成

        IPV6写法:2022:jli2:ij28:oi98:12yj:0000:1230
        
    • 公网(互联网)ip / 私网(局域网)ip

      • 192.168.xx.xx属于局域网专门给组织机构使用的
      • ABCD类地址
  • 域名:记忆IP问题

    • IP地址操作类相关的代码
    package com.yu.lesson01;
    
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    
    //测试IP
    public class TestInetAddress {
        public static void main(String[] args) {
            try {
                //查询本机地址
                InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
                System.out.println(inetAddress1);
                InetAddress inetAddress3 = InetAddress.getByName("localhost");
                System.out.println(inetAddress3);
                InetAddress inetAddress4 = InetAddress.getLocalHost();
                System.out.println(inetAddress4);
    
                //查询网站ip地址
                InetAddress inetAddress2 = InetAddress.getByName("www.baidu.com");
                System.out.println(inetAddress2);
    
                //常用方法
                System.out.println(inetAddress2.getAddress());
                System.out.println(inetAddress2.getCanonicalHostName());//规范的名字
                System.out.println(inetAddress2.getHostAddress());//ip
                System.out.println(inetAddress2.getHostName());//域名,或者自己电脑的名字
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
    
        }
    }
    
    

1.2.2、端口

  • 定义:

    最初,端口是计算机上的一个物理接口(USB应该也算),通过这个接口,外部设备可以连接到计算机,如果把计算机比作一个国度的话,那么端口(port)就是码头,通过这个码头,从外地来的船只的货物(外部设备的信息)可以到达本国,而且本国的出口货物(计算机产生的信息)也可以通过船只(可以理解为连接线)到达另一个国度。在计算机网络领域,端口也可以比作为码头,通过这个码头,计算机可以与互联网(除本机外的所有世界上所有联网设备)进行交互。

  • 端口表示计算机上的一个程序的进程:

    • 不同的进程有不同的端口号。用来区分软件。

    • 端口被规定0~65535

    • TCP,UDP:65535*2 单个协议下,端口号不能冲突。

    • 端口分类:

      • 公有端口 0~1023

        • HTTP:80
        • HTTPS: 443
        • FTP: 21
        • Telent:23
      • 程序注册端口:1024~49151,分配用户或者程序

        • Tomcat:8080
        • MySQL:3306
        • Oracle:1521
      • 动态、私有:49152~65535

        常用的网络DOS命令: netstat -ano 查看所有的端口
                         netstat -ano|findstr"" 查看指定的端口
                         tasklist|findstr "" 查看指定的端口的进程
        
    • 常用的端口代码

      package com.yu.lesson01;
      
      import java.net.InetSocketAddress;
      
      public class TestInetSocketAddress {
          public static void main(String[] args) {
              InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1", 8080);
              InetSocketAddress socketAddress2 = new InetSocketAddress("localhost", 8080);
              System.out.println(socketAddress);
              System.out.println(socketAddress2);
      
              System.out.println(socketAddress.getAddress());
              System.out.println(socketAddress.getHostName());//地址
              System.out.println(socketAddress.getPort());//端口
          }
      }
      
      

1.2.3、通信协议

  • 定义:

    通信协议是指双方实体完成通信或服务所必须遵循的规则和约定。通过通信信道和设备互连起来的多个不同地理位置的数据通信系统,要使其能协同工作实现信息交换和资源共享,它们之间必须具有共同的语言。交流什么、怎样交流及何时交流,都必须遵循某种互相都能接受的规则。这个规则就是通信协议。

  • 网络通信协议:速率、传输码率、代码结构、传输控制…

  • TCP/IP协议族

    • TCP: 用户传输协议
    • UDP:用户数据报协议
  • TCP与UDP的对比

    • TCP:比喻为打电话(连接稳定)传输控制协议 (Transmission Control Protocol)

      • TCP协议是面向连接的通信协议,即传输数据之前,在发送端和接收端建立逻辑连接,然后再传输数据,它提供了两台计算机之间可靠无差错的数据传输。在TCP连接中必须要明确客户端与服务器端,由客户端向服务端发出连接请求,每次连接的创建都需要经过"三次握手”

      • 三次握手: TCP协议中,在发送数据的准备阶段,客户端与服务器之间的三次交互,以保证连接的可靠
        第一次握手:客户端向服务器端发出连接请求,等待服务器确认
        第二次握手:服务器端向客户端回送一个响应, 通知客户端收到了连接请求
        第三次握手:客户端再次向服务器端发送确认信息,确认连接

      • 完成三次握手,连接建立后,客户端和服务器就可以开始进行数据传输了。由于这种面向连接的特性,TCP协议可以保证传输数据的安全,所以应用十分广泛。例如.上传文件、下载文件、 浏览网页等

        在这里插入图片描述

    • UDP:比喻为发短信(不连接,不稳定)

      • 用户数据报协议(User Datagram Protocol)
      • UDP是无连接通信协议,即在数据传输时,数据的发送端和接收端不建立逻辑连接。简单来说,当一台计算机向另外一台计算机发送数据时,发送端不会确认接收端是否存在,就会发出数据,同样接收端在收到数据时,也不会向发送端反馈是否收到数据。
        由于使用UDP协议消耗资源小,通信效率高,所以通常都会用于音频、视频和普通数据的传输
      • 例如视频会议通常采用UDP协议, 因为这种情况即使偶尔丢失一两个数据包, 也不会对接收结果产生太大影响。但是在使用UDP协议传送数据时,由于UDP的面向无连接性,不能保证数据的完整性,因此在传输重要数据时不建议使用UDP协议。
1.2.3.1、TCP
  • TCP通信原理:

    TCP通信协议是一种可靠的网络协议,它在通信的两端各建立-个Socket对象,从而在通信的两端形成网络虚拟链路,一旦建立 了虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信
    Java对基于TCP协议的的网络提供了良好的封装,使用Socket对象来代表两端的通信端口,并通过Socket产生0流来进行网络通信
    Java为客户端提供了Socket类,为服务器端提供了ServerSocket类

  • TCP中相应代码

    客户端:

    1. 连接服务器Scoket
    2. 发送消息
    package com.yu.lesson02;
    
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.InetAddress;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    //客户端
    public class TcpClientDemo01 {
        public static void main(String[] args) {
            Socket socket = null;
            OutputStream os = null;
            try {
                //1.要知道服务器的地址,端口号
                InetAddress serverIP = InetAddress.getByName("127.0.0.1");
                int port = 9999;
                //2、创建一个socket连接
                socket = new Socket(serverIP,port);
                //3.发送消息IO流
                os = socket.getOutputStream();
                os.write("你好".getBytes());
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                if (os!=null){
                    try {
                        os.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (socket!=null){
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
    
            }
        }
    }
    
    

    服务器:

    1. 建立服务的端口ServerSocket
    2. 等待用户的链接accpet
    3. 接收用户的消息
    package com.yu.lesson02;
    
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    //服务端
    public class TcpServerDemo01 {
        public static void main(String[] args) {
    
            ServerSocket serverSocket = null;
            Socket socket = null;
            InputStream is = null;
            ByteArrayOutputStream baos = null;
            try {
                //1.新建一个地址
                 serverSocket = new ServerSocket(9999);
                //2.等待客户端连接过来
                while (true){
                    socket = serverSocket.accept();
                    //3.读取客户端的消息
                    is = socket.getInputStream();
                    //管道流
                    baos = new ByteArrayOutputStream();
                    byte[] buffer = new byte[1024];
                    int len;
                    while ((len=is.read(buffer))!=-1){
                        baos.write(buffer,0,len);
                    }
                    System.out.println(baos.toString());
                }
    
    
    
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                //关闭资源
                if(baos!=null){
                    try {
                        baos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (is!=null){
                    try {
                        is.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (socket!=null){
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (serverSocket!=null){
                    try {
                        serverSocket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
    
        }
    }
    
    

    TCP文件上传:

    服务器端

    package com.yu.lesson02;
    
    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    //服务端
    public class TcpServerDemo02 {
        public static void main(String[] args) throws IOException {
            //1.创建服务
            ServerSocket serverSocket = new ServerSocket(9000);
            //2.监听客户端的链接
            Socket socket = serverSocket.accept();//阻塞式监听,会一直等待客户端连接
            //3.获取输入流
            InputStream is = socket.getInputStream();
    
            //4.文件输出
            FileOutputStream fos = new FileOutputStream(new File("receive.jpg"));
            byte[] buffer = new byte[1024];
            int len;
            while ((len=is.read(buffer))!=-1){
                fos.write(buffer,0,len);
            }
    
            //通知客户端我接收完毕了
            OutputStream os = socket.getOutputStream();
            os.write("我接受完毕了,你可以断开".getBytes());
    
    
            //5.释放资源
            fos.close();
            is.close();
            socket.close();
            serverSocket.close();
    
        }
    }
    
    

    客户端:

    package com.yu.lesson02;
    
    
    import java.io.*;
    import java.net.InetAddress;
    import java.net.Socket;
    
    //客户端
    public class TcpClientDemo02 {
        public static void main(String[] args) throws Exception{
            //1.创建一个客户端连接
            Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9000);
            //2.创建一个输出流
            OutputStream os = socket.getOutputStream();
    
            //3.文件流
            FileInputStream fis = new FileInputStream(new File("C:\\Users\\86132\\Desktop\\header.jpg"));
            //4.写出文件
            byte[] buffer = new byte[1024];
            int len;
            while ((len=fis.read(buffer))!=-1){
                os.write(buffer,0,len);
            }
            //通知服务器,结束
            socket.shutdownOutput();
    
            //确定服务器接收完毕,才能够断开连接
            InputStream inputStream = socket.getInputStream();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buffer2 = new byte[2014];
            int len2;
            while ((len2=inputStream.read(buffer2))!=-1){
                baos.write(buffer2,0,len2);
            }
            System.out.println(baos.toString());
            //5.释放资源
            baos.close();
            inputStream.close();
            fis.close();
            os.close();
            socket.close();
    
        }
    }
    
    
1.2.3.2、UDP
  • UDP通信原理
    UDP协议是一种不可靠的网络协议, 它在通信的两端各建立一个Socket对象, 但是这两个Socket只是发送,接收数据的对象因此对于基于UDP协议的通信双方而言,没有所谓的客户端和服务器的概念
    Java提供了DatagramSocket类作为基于UDP协议的Socket

  • UDP相关代码

    发送端

    package com.yu.lesson03;
    
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.SocketException;
    
    //不需要连接服务器
    public class UdpClientDemo01 {
        public static void main(String[] args) throws Exception {
            //1.建立一个Socket
            DatagramSocket socket = new DatagramSocket();
    
            //2.建个包
            String msg = "你好,服务器";
            //发送对象
            InetAddress localhost = InetAddress.getByName("localhost");
            int port = 9999;
            //数据,数据的长度起始
            DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port);
    
            //3.发送包
            socket.send(packet);
    
            //4.释放资源
            socket.close();
    
        }
    }
    
    

    接收端:

    package com.yu.lesson03;
    
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.SocketException;
    
    //等待客户端的链接
    public class UdpServerDemo01 {
        public static void main(String[] args) throws Exception {
            //开放端口
            DatagramSocket socket = new DatagramSocket();
            //接收数据包
            byte[] buffer = new byte[1024];
            DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
    
            socket.receive(packet);//阻塞接收
    
            System.out.println(packet.getAddress().getHostAddress());
            System.out.println(new String(packet.getData(),0,packet.getLength()));
            //释放资源
            socket.close();
        }
    }
    
    

    UDP聊天实现

    循环发送消息

    package com.yu.chat;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetSocketAddress;
    import java.net.SocketException;
    
    public class UdpSenderDemo01 {
        public static void main(String[] args) throws Exception {
    
            DatagramSocket socket = new DatagramSocket(8888);
    
            //准备数据:控制台读取 System.in
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    
            while (true){
                String data = reader.readLine();
                byte[] datas = data.getBytes();
                DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress("localhost",6666));
    
                socket.send(packet);
                if (data.equals("bye")){
                    break;
                }
            }
    
    
            socket.close();
    
    
        }
    }
    
    

    循环接收消息

    package com.yu.chat;
    
    
    
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.SocketException;
    
    public class UdpReceiveDemo01 {
        public static void main(String[] args) throws Exception {
            DatagramSocket socket = new DatagramSocket(6666);
    
            while (true){
                //准备接收包
                byte[] container = new byte[1024];
                DatagramPacket packet = new DatagramPacket(container,0,container.length);
                socket.receive(packet);//
                //断开连接
                byte[] data = packet.getData();
                String receivedata = new String(data, 0, data.length);
    
                System.out.println(receivedata);
                if(receivedata.equals("bye")){
                    break;
                }
    
            }
    
             socket.close();
    
    
    
        }
    }
    
    

    在线咨询:两个人都可以是发送方,也都可以是接收方!

    发送消息

    package com.yu.chat;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetSocketAddress;
    
    
    public class TalkSend implements Runnable {
        DatagramSocket socket = null;
        BufferedReader reader = null;
    
        private int fromPort;
        private String toIP;
        private int toPort;
    
        public TalkSend(int fromPort, String toIP, int toPort) {
            this.fromPort = fromPort;
            this.toIP = toIP;
            this.toPort = toPort;
    
            try {
                 socket = new DatagramSocket(fromPort);
                reader = new BufferedReader(new InputStreamReader(System.in));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void run() {
    
    
            while (true){
                try {
                    String data = reader.readLine();
                    byte[] datas = data.getBytes();
                    DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress(this.toIP,this.toPort));
    
                    socket.send(packet);
                    if (data.equals("bye")){
                        break;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            socket.close();
    
    
        }
        }
    }
    
    

    接收消息

    package com.yu.chat;
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.SocketException;
    
    public class TalkRecieveDemo01 implements Runnable{
    
        DatagramSocket socket = null;
        private int port;
        private String msgFrom;
    
        public TalkRecieveDemo01(int port,String msgFrom) {
            this.port = port;
            this.msgFrom = msgFrom;
            try {
                 socket = new DatagramSocket(port);
            } catch (SocketException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void run() {
    
    
            while (true){
                try {
                    //准备接收包
                    byte[] container = new byte[1024];
                    DatagramPacket packet = new DatagramPacket(container,0,container.length);
                    socket.receive(packet);
                    //断开连接
                    byte[] data = packet.getData();
                    String receivedata = new String(data, 0, data.length);
    
                    System.out.println(msgFrom+":"+receivedata);
                    if(receivedata.equals("bye")){
                        break;
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
    
            }
    
            socket.close();
        }
    }
    
    

    学生:

    package com.yu.chat;
    
    public class TalkStudent {
        public static void main(String[] args) {
            //开启两个线程
            new Thread(new TalkSend(7777,"localhost",9999)).start();
            new Thread(new TalkRecieveDemo01(8888,"老师")).start();
        }
    }
    
    

    老师:

    package com.yu.chat;
    
    public class TalkTeacher {
        public static void main(String[] args) {
            new Thread(new TalkSend(5555,"localhost",8888)).start();
            new Thread(new TalkRecieveDemo01(9999,"学生")).start();
        }
    }
    
    
1.2.3.3、URL

统一资源定位符:定位资源的额,定位互联网的资源

DNS域名解析 www.baidu.com xxx.xxx.xxx

  • 协议://ip地址:端口号/项目名/资源

    package com.yu.lesson04;
    
    import java.net.MalformedURLException;
    import java.net.URL;
    
    public class URLDemo01 {
        public static void main(String[] args) throws MalformedURLException {
            //C:\Users\86132\Desktop\tomcat-8.5.82\webapps\ywj
            URL url = new URL("http://localhost:8080/helloworld/index.jsp?username=ywj&password=123");
            System.out.println(url.getProtocol());//协议
            System.out.println(url.getHost());//主机ip
            System.out.println(url.getPort());//端口
            System.out.println(url.getPath());//文件
            System.out.println(url.getFile());//文件全路径
            System.out.println(url.getQuery());//参数
    
        }
    }
    
    
    package com.yu.lesson04;
    
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    
    public class urlDown {
        public static void main(String[] args) throws Exception {
            //1.下载地址
            URL url = new URL("http://localhost:8080/ywj/Sj.txt");
    
            //2.连接到这个资源 HTTP
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
    
            InputStream inputStream = urlConnection.getInputStream();
    
            FileOutputStream fos = new FileOutputStream("Sj.txt");
    
            byte[] buffer = new byte[1024];
            int len;
            while ((len=inputStream.read(buffer))!=-1){
                fos.write(buffer,0,len);//写出这个数据
            }
            fos.close();
            inputStream.close();
            urlConnection.disconnect();//断开连接
        }
    }
    
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值