java网络编程

网络编程

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

网络通信的要素

  • 通信双方的地址:

    • ip
    • 端口号
  • 规则:网络通信的协议

  • TCP/IP参考模型:


  • 小结:

    1. 网络编程中两个主要的问题
      • 如何准确的定位到网络上的一台或多台主机
      • 找到主机之后如何进行通信
    2. 网络编程中的要素
      • IP和端口号
      • 网络通信协议:udp,tcp
    3. 万物皆对象

IP

  • IP地址:InetAddress

    • 唯一定位一台网络上

    • 127.0.0.1:本机localhost

    • IP地址分类:

      1. IP地址分类:ipv4/ipv6

        • IPv4 127.0.0.1,4个字节组成

        • IPV6 :128位,8个无符号整数

      2. 公网(互联网)-私网(局域网)

        • IP地址分为A,B,C,D,E五类

        • A类保留给政府机构,B类分配给中等规模的公司,C类分配给任何需要的人,D类用于组播,E类用于实验,各类可容纳的地址数目不同

        • A类为8位、B类为16位、C类为24位、D类位多bai播地址

    • 域名:解决了记忆IP问题

    package com.wu.网络编程;
    
    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);///127.0.0.1
                InetAddress inetAddress3 = InetAddress.getByName("localhost");
                System.out.println(inetAddress3);//localhost/127.0.0.1
                InetAddress inetAddress4 = InetAddress.getLocalHost();
                System.out.println(inetAddress4);//HP/192.168.139.1
                //查询网站ip地址
                InetAddress inetAddress2 = InetAddress.getByName("www.baidu.com");
                System.out.println(inetAddress2);//www.baidu.com/110.242.68.3
    
                //常用方法
                System.out.println(inetAddress2.getAddress());
                System.out.println(inetAddress2.getCanonicalHostName());//规范名字
                System.out.println(inetAddress2.getHostAddress());//ip
                System.out.println(inetAddress2.getHostName());//域名 或自己电脑的名字
                //[B@1b6d3586
                //110.242.68.4
                //110.242.68.4
                //www.baidu.com
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
        }
    }
    

端口

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

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

  • 被规定0~65535

  • 分TCP,UDP端口,各有65536个,单个协议下,端口号不能冲突

  • 端口分类:

    • 公有端口: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 "5900" #查看指定的端口
        tasklist|findstr "8696" #查看指定端口的进程
        
    package com.wu.网络编程;
    
    import java.net.InetSocketAddress;
    
    public class TestInetSocketAddress {
        public static void main(String[] args) {
            InetSocketAddress inetSocketAddress1 = new InetSocketAddress("127.0.0.1", 8080);
            InetSocketAddress inetSocketAddress2 = new InetSocketAddress("localhost", 8080);
            System.out.println(inetSocketAddress1);
            System.out.println(inetSocketAddress2);
    
            System.out.println(inetSocketAddress1.getAddress());
            System.out.println(inetSocketAddress1.getHostName());//地址
            System.out.println(inetSocketAddress1.getPort());//端口
            // /127.0.0.1:8080
            // localhost/127.0.0.1:8080
            // /127.0.0.1
            // 127.0.0.1
            // 8080
    
        }
    }
    

通信协议

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

  • TCP/IP协议簇

  • 重要:

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

    TCP:打电话

    • 连接,稳定

    • 三次握手 四次挥手(连接终止协议)

      第一次握手:建立连接时,客户端发送syn包(seq=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。
      第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(seq=k),即SYN+ACK包,此时服务器进入SYN_RECV状态。
      第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
      完成三次握手,客户端与服务器开始传送数据,
      
      由于TCP连接是全双工的,因此每个方向都必须单独进行关闭
      (1) TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送。
      (2) 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。
      (3) 服务器关闭客户端的连接,发送一个FIN给客户端。
      (4) 客户端发回ACK报文确认,并将确认序号设置为收到序号加1。
      
    • 客户端、服务端

    • 传输完成,释放连接

    UDP:发短信

    • 不连接,不稳定
    • 客户端、服务端:没有明确的界限
    • 不管有没有准备好,都可以发送
    • DDOS:洪水攻击(饱和攻击)

TPC

  • 客户端

    1. 连接服务器 Socket
    2. 发送消息
    //客户端
    public class ClientDemo01 {
        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;
                //创建一个socket连接
                socket = new Socket(serverIP,port);
                //发送消息 IO流
                os = socket.getOutputStream();
                os.write("aaa".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. 等待用户的连接 accept
    3. 接收用户的消息
    //服务端
    public class ServerDemo01 {
        public static void main(String[] args) {
            ServerSocket serverSocket =null;
            Socket socket = null;
            InputStream is =null;
            ByteArrayOutputStream baos=null;
            try {
                //1.服务器要有一个地址
                serverSocket = new ServerSocket(9999);
                //等待客户端连接过来
                socket = serverSocket.accept();
                //读取客户端的消息
                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 (Exception 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();
                    }
                }
            }
        }
    }
    

文件上传

  • 客户端

    public class ClientDemo02 {
        public static void main(String[] args) throws Exception {
            //1.创建一个Socket连接
            Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000);
            //2.创建一个输出流
            OutputStream os = socket.getOutputStream();
            FileInputStream fis = new FileInputStream(new File("aaa.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());//我接受完毕了
            //关闭资源
            baos.close();
            inputStream.close();
            fis.close();
            os.close();
            socket.close();
        }
    }
    
  • 服务器

    //服务端
    public class ServerDemo02 {
        public static void main(String[] args) throws Exception{
            //创建服务
            ServerSocket serverSocket = new ServerSocket(9000);
            //监听客户端的连接
            Socket socket = serverSocket.accept();//阻塞式监听,会一直等待客户端连接
            //获取输入流
            InputStream is = socket.getInputStream();
            //文件输出
            FileOutputStream fos = new FileOutputStream(new File("bbb.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());
            //关闭资源
            os.close();
            fos.close();
            is.close();
            socket.close();
            serverSocket.close();
        }
    }
    

Tomcat

  • 服务端:
    • 自定义S
    • Tomcat服务器S
  • 客户端
    • 自定义C
    • 浏览器B

UDP

  • 发短信:不用连接,需要知道对方的地址

1. 发送消息

  • 发送端

    //不需要连接服务器
    public class ClientDemo01 {
        public static void main(String[] args) throws Exception {
            //1.建立一个socket
            DatagramSocket socket = new DatagramSocket();
            //2.建个包
            String msg = "你好服务器";
            //发送给谁
            InetAddress localhost = InetAddress.getByName("localhost");
            int port=9090;
            DatagramPacket packet = new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,localhost,port);
            //3.发送包
            socket.send(packet);
            socket.close();
        }
    }
    
  • 接收端

    //还是要等待客户端的连接
    public class ServerDemo01 {
        public static void main(String[] args) throws Exception {
            //开放端口
            DatagramSocket socket = new DatagramSocket(9090);
            //接收数据包
            byte[] buffer = new byte[1024];
            DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
            socket.receive(packet);//阻塞接收
            System.out.println(new String(packet.getData(),0,packet.getLength()));//你好服务器
            System.out.println(packet.getAddress().getHostAddress());// 127.0.0.1
            socket.close();
        }
    }
    

2.咨询

  • 一方发送消息,一方接收消息,直到发送字符串“bye”结束连接

    public class SenderDemo01 {
        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[] bytes = data.getBytes();
                DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length, new InetSocketAddress("localhost", 6666));
                socket.send(packet);
                if (data.equals("bye")) {
                    break;
                }
            }
            socket.close();
        }
    }
    
    
    public class ReceiveDemo01 {
        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);//阻塞式接收包裹
                //断开连接 bye
                byte[] data = packet.getData();//读取数据
                String receiveData = new String(data, 0, packet.getLength());
                System.out.println(receiveData);
                if (receiveData.equals("bye")) {
                    break;
                }
    
            }
            socket.close();
    
        }
    }
    
    
  • 在线咨询双方都即是发送方又是接收方(运用到多线程)

    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 (SocketException e) {
                e.printStackTrace();
            }
    
        }
    
        @Override
        public void run() {
            try {
                while (true) {
                    String data = reader.readLine();
                    byte[] bytes = data.getBytes();
                    DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length, new InetSocketAddress(this.toIP, this.toPort));
                    socket.send(packet);
                    if (data.equals("bye")) {
                        break;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            socket.close();
        }
    }
    
    
    public class TalkReceive implements Runnable{
        DatagramSocket socket =null;
        private int port;
        private String msgFrom;
    
        public TalkReceive(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);//阻塞式接收包裹
                    //断开连接 bye
                    byte[] data = packet.getData();//读取数据
                    String receiveData = new String(data, 0, packet.getLength());
                    System.out.println(msgFrom+":"+receiveData);
                    if (receiveData.equals("bye")) {
                        break;
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
    
            }
            socket.close();
        }
    }
    
    
    public class TalkTeacher {
        public static void main(String[] args) {
            new Thread(new TalkSend(5555,"localhost",8888)).start();
            new Thread(new TalkReceive(9999,"学生")).start();
        }
    }
    
    
    public class TalkTeacher {
        public static void main(String[] args) {
            new Thread(new TalkSend(5555,"localhost",8888)).start();
            new Thread(new TalkReceive(9999,"学生")).start();
        }
    }
    
    

URL

  • https://www.baidu.com/

  • 统一资源定位符:定位互联网上某一个资源的

  • DNS 域名解析:把一个域名解析成IP


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

    public class URLDemo01 {
        public static void main(String[] args) throws MalformedURLException {
            URL url = new URL("http://localhost:8080/helloworld/index.jsp?username=aa&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());//参数
            //http
            //localhost
            //8080
            ///helloworld/index.jsp
            ///helloworld/index.jsp?username=aa&password=123
            //username=aa&password=123
            
        }
    }
    

  • 下载网络上的资源

    public class UrlDown {
        public static void main(String[] args) throws Exception {
            //1.下载地址
            URL url = new URL("http://localhost:8080/wu/securityfile.txt");
            //2.连接到这个资源 HTTP
            HttpURLConnection urlConnection=(HttpURLConnection)url.openConnection();
            InputStream inputStream = urlConnection.getInputStream();
            FileOutputStream fos = new FileOutputStream("aaa.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();//断开连接
        }
    }
    
    
posted @ 2021-01-17 13:28  迪迦是真的  阅读(124)  评论(0)    收藏  举报
//复制代码按钮 //代码行号 //评论