网络编程network

网络编程(network programming

1.1、概述


地球村:你在北京,你有一个美国的朋友!

信件:

计算机网络:

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

网络编程的目的:

无线电台…传播、交流信息,数据交换、通信

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

1.如何准确的定位网络上的一台主机 127.0.0.1 :端口,定位到这个计算机上的某个资源

2.找到了这个主机,如何传输数据呢?

Javaweb:网页编程 B/S

网络编程:TCP/IP C/S

1.2、网络通信的要素


如何实现网络的通信?

通信双方的地址:

  • ip
  • 端口号

规则:网络通信的协议

OSI(Open System Interconnection)开放式系统互联

(https://note.youdao.com/yws/public/resource/174d431020d0434176321a9c7ec19362/xmlnote/01FFF3ACC38E4BEAB3ECC7850F33843E/315)

TCP/IP模型

一组用于实现网络互连的通信协议,将协议分为四个层次


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

1.3、IP

IP协议:Internet Protocol 互联网协议/网际协议。

  • 负责数据从一台机器发送到另一台机器
  • 给互联网每台设备分配一个唯一标识、数字标签(IP地址)

InetAddress类

表示互联网协议(IP)地址对象,封装了与该协议相关的所有信息,并提供获取信息的常用方法

  • 唯一定位一台网络上的计算机

  • 127.0.0.1:本机localhost

  • ip地址分类

    • IPV4/IPV6

      • IPV4 127.0.0.1 4个字节组成, 0~255 42亿;30亿都在北美,亚洲4亿,2011年就用尽了(资源耗尽)

      • IPV6 16字节128位整数,并分成8段16进制数!0~65535

        2001:0bb2:aaaa:0015:0000:0000:1aaa:1312
        

  • 公网(互联网)私网(局域网)

    • 192.168.xx.xx,专门给组织内部使用的
    • ABCD地址
  • 域名:记忆IP问题!

    • IP:www.vip.com 万网
package com.zhang;

import java.net.InetAddress;
import java.net.UnknownHostException;

//测试IP
public class TestInetAddress {
    
    
    public static void main(String[] args) {
    
    
        try {
    
    
            //(1)创建本机Ip地址对象
            // 1.1、getLocalHost方法
            InetAddress ia1 = InetAddress.getLocalHost();
            System.out.println("ip地址:" + ia1.getHostAddress() + "\t主机名:" + ia1.getHostName());
            // 1.2、getByName("ip地址")
            InetAddress ia2 = InetAddress.getByName("192.168.1.4");
            System.out.println("ip地址:" + ia2.getHostAddress() + "\t主机名:" + ia2.getHostName());
            //1.3、getByName("127.0.0.1")
            InetAddress ia3 = InetAddress.getByName("127.0.0.1");
            System.out.println("ip地址:" + ia3.getHostAddress() + "\t主机名:" + ia3.getHostName());
            //1.4、getByName("localhost")
            InetAddress ia4 = InetAddress.getByName("localhost");
            System.out.println("ip地址:" + ia4.getHostAddress() + "\t主机名:" + ia4.getHostName());

            //(2)创建局域网的Ip地址对象
            InetAddress ia5 = InetAddress.getByName("192.168.1.45");
            System.out.println("ip地址:" + ia5.getHostAddress() + "\t主机名:" + ia5.getHostName());
            System.out.println("是否可达:" + ia5.isReachable(2000));


            //(3) 创建外网Ip地址对象
            InetAddress bd = InetAddress.getByName("www.baidu.com");
            System.out.println("ip地址:" + bd.getHostAddress() + "\t主机名:" + bd.getHostName());
            System.out.println("是否可达:" + bd.isReachable(2000));
            InetAddress vip = InetAddress.getByName("www.vip.com");
            System.out.println("ip地址:" + vip.getHostAddress() + "\t主机名:" + vip.getHostName());

            //获取多个Ip地址对象
            InetAddress[] ias = InetAddress.getAllByName("www.baidu.com");
            for (InetAddress inetAddress : ias) {
    
    
                System.out.println(inetAddress.getHostAddress());
            }
        } catch (UnknownHostException e) {
    
    
            e.printStackTrace();
        }
    }
}

1.4、端口


端口号:Port 表示计算机上的一个程序的进程;在通信实体上进行网络通讯程序的唯一标识

  • 不同的进程有不同的端口号!用来区分软件
  • 被规定 0~65535
  • TCP,UDP:65535 tcp:80 udp:80 ,单个协议下,端口号不能冲突
  • 端口分类
    • 公认端口 0~1023
      • HTTP:80
      • HTTPS:443
      • FTP:21
      • Telent:23
    • 程序注册端口:1024~49151,分配用户或者程序
      • Tomcat:8080
      • MySql:3306
      • Oracle:1521
      • SMTP:25
    • 动态、私有端口:49152~65535
netstat -ano #查看所有的端口
tasklist|findstr "13900"	#查看指定端口的进程
package com.zhang;

import java.net.InetSocketAddress;

public class TestInetSocketAddress {
    
    
    public static void main(String[] args) {
    
    
        InetSocketAddress SocketAddress1 = new InetSocketAddress("127.0.0.1", 8080);
        InetSocketAddress SocketAddress2 = new InetSocketAddress("localhost", 8080);
        System.out.println(SocketAddress1);
        System.out.println(SocketAddress2);

        System.out.println(SocketAddress1.getAddress());
        System.out.println(SocketAddress1.getHostName());       //地址
        System.out.println(SocketAddress1.getPort());       //端口
    }
}

1.5、通信协议


协议:约定,就好比我们现在说的是普通话;

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

问题:非常的复杂?

大事化小:分层!

TCP/IP协议簇实际上是一组协议

重要:

  • TCP:用户传输协议(打电话)
  • UDP:用户数据报协议(发短信)

出名的协议:

  • TCP:用户传输协议
  • IP:网络互连协议

TCP UDP对比

TCP:打电话

  • 连接,稳定

  • 三次握手 四次分(挥)手

    最少需要三次,保证稳定连接
    A:你瞅啥?
    B:瞅你咋地?
    A:干一场!	(建立连接)
    
    A:我要断开了
    B:我知道你要断开了
    B:你真的真的断开了吗?(确认询问)
    A:我真的断开了	(回应)
    
  • 客户端、服务端

  • 传输完成,释放连接,效率低

UDP:发短信

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

1.6、TCP


TCP协议:Transmission Control Protocol 传输控制协议

  • 是一种面向连接的、可靠的、基于字节流的传输层通信协议,数据大小无限制,建立连接的过程需要三次握手,断开连接的过程需要四次挥手。

客户端

Sock编程:(建立连接、接收请求、发送响应)

  • socket(套接字)是网络中的一个通信节点
  • 分为客户端Socket与服务器ServerSocket
  • 通信要求:IP地址+端口号

客户端发送数据给服务器端

  1. 连接服务器 Socket

  2. 发送消息

    package com.zhang;
    
    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.要知道服务器的IP地址  端口号
                InetAddress serverIP = InetAddress.getByName("127.0.0.1");
                int port = 6666;
                //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. 等待用户的连接 accept
  3. 接收用户的消息
package com.zhang;

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) {
    
    
        ByteArrayOutputStream baos = null;
        InputStream is = null;
        Socket socket = null;
        ServerSocket serverSocket = null;
        try {
    
    
            //1.我得有一个地址
            serverSocket = new ServerSocket(6666);
            while (true) {
    
    
                //2.等待客户端连接进来
                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());
            }
            /*
            byte[] buffer = new byte[1024];
            int len;
            while ((len = is.read(buffer)) != -1) {
                String msg = new String(buffer, 0, len);
                System.out.println(msg);
            }
             */
        } 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();
                }
            }
        }
    }
}

客户端上传文件给服务器

服务器端

package com.zhang.lession2;

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

public class TCPServerDemo01 {
    
    
    public static void main(String[] args) throws Exception {
    
    
        //1.创建服务
        ServerSocket serverSocket = new ServerSocket(9000);
        //2.监听客户端的连接
        Socket socket = serverSocket.accept();//阻塞式监听,会一直等待客户端连接
        //3.获取输入流
        InputStream is = socket.getInputStream();
        //文件输出
        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());

        //释放资源
        fos.close();
        is.close();
        socket.close();
    }
}

客户端

package com.zhang.lession2;

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

public class TCPClientDemo2 {
    
    
    public static void main(String[] args) throws Exception {
    
    
        //1.创建一个Socket连接,指定服务器IP+端口号
        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000);
        //2.创建一个输出流
        OutputStream os = socket.getOutputStream();

        //读取文件
        FileInputStream fis = new FileInputStream(new File("7.jpg"));
        //4.写出文件
        byte[] buffer = new byte[1024];
        int len;
        while ((len = fis.read(buffer)) != -1) {
    
    
            os.write(buffer, 0, len);
        }

        //通知服务器,我已经传输完毕了
        socket.shutdownOutput();

        //确认服务器接收完毕,才能够断开连接
        InputStream is = socket.getInputStream();
        //String byte[]
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        byte[] buffer2 = new byte[1024];
        int len2;
        while ((len = is.read(buffer2)) != -1) {
    
    
            baos.write(buffer2, 0, len);
        }
        System.out.println(baos.toString());

        //5.关闭资源
        baos.close();
        is.close();
        fis.close();
        fis.close();
        socket.close();
    }
}

使用TCP实现接收多个客户端请求

线程类

package com.zhang;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;

public class SocketThread extends Thread {
    
    
    private Socket socket;

    public SocketThread(Socket socket) {
    
    
        this.socket = socket;
    }

    public SocketThread() {
    
    
    }

    @Override
    public void run() {
    
    
        if (socket != null) {
    
    
            BufferedReader br = null;
            try {
    
    
                InputStream is = socket.getInputStream();
                br = new BufferedReader(new InputStreamReader(is, "utf-8"));
                while (true) {
    
    
                    String data = br.readLine();
                    if (data == null) break;     //客户端已经关闭!
                    System.out.println(socket.getInetAddress() + "说:" + data);
                    if (data.equals("886") || data.equals("再见")) break;
                }
            } catch (IOException e) {
    
    
                e.printStackTrace();
            } finally {
    
    
                try {
    
    
                    if (br != null) br.close();
                    if (socket != null) socket.close();
                    System.out.println(socket.getInetAddress() + "退出了!");
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }
}

服务器端

package com.zhang;

import java.net.ServerSocket;
import java.net.Socket;

/**
 * 使用TCP实现多个客户端请求
 */
public class TCPMultiServer {
    
    
    public static void main(String[] args) throws Exception {
    
    
        //1.创建ServerSocket
        ServerSocket listener = new ServerSocket(10086);
        //2.调用accept(),接收客户端请求
        System.out.println("服务器已启动!");
        while (true) {
    
    
            Socket socket = listener.accept();
            System.out.println(socket.getInetAddress() + "进来了!");
            //创建线程对象,负责接收数据
            new SocketThread(socket).start();
        }
    }
}

客户端

package com.zhang;

import java.io.BufferedWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;

/**
 * TCP客户端,一直向服务器发送数据
 */
public class TCPMultiClient {
    
    
    public static void main(String[] args) throws Exception {
    
    
        //1.创建socket
        Socket socket = new Socket(InetAddress.getLocalHost(), 10086);
        //2.获取输出流
        OutputStream os = socket.getOutputStream();
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os, "utf-8"));
        //3.控制台输入
        Scanner input = new Scanner(System.in);
        while (true) {
    
    
            String data = input.nextLine();
            bw.write(data);
            bw.newLine();   //发送换行符
            bw.flush();
            if (data.equals("886") || data.equals("再见")) break;
        }
        //4.关闭流,释放资源
        bw.close();
        socket.close();
    }
}

1.7、UDP


UDP协议:User Datagram Protocol 用户数据报协议

  • 是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,每个包的大小最大只能是64KB

tomcat

服务端

  • Tomcat服务器 C/S Java后台开发

客户端

  • 浏览器 B/S

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

发送端

package com.zhang.lession3;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

//不需要服务器
public class UdpClientDemo01 {
    
    
    public static void main(String[] args) throws Exception {
    
    
        //1.建立一个Socket
        DatagramSocket socket = new DatagramSocket();

        //2.建个包
        String msg = "你好,服务器!";

        //发送给谁
        InetAddress localhost = InetAddress.getByName("127.0.0.1");
        int port = 6060;
        //数据,数据的长度起始,要发送给谁
        DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port);
        //发送包
        socket.send(packet);
        //4.关闭流
        socket.close();
    }
}

接收端

package com.zhang.lession3;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

//等待客户端的连接
public class UdpServerDemo01 {
    
    
    public static void main(String[] args) throws Exception {
    
    
        //开放断开
        DatagramSocket socket = new DatagramSocket(6060);
        //接收数据包
        byte[] buffer = new byte[1024];
        int len;
        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();
    }
}

咨询

循环发送消息

package com.zhang.lession4;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

public class UdpSenderDemo01 {
    
    
    public static void main(String[] args) throws Exception {
    
    
        DatagramSocket socket = new DatagramSocket(8888);
        while (true) {
    
    
            //准备数据: 控制台读取,System.in
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            String data = reader.readLine();
            byte[] dates = data.getBytes();
            DatagramPacket packet = new DatagramPacket(dates, 0, dates.length, new InetSocketAddress("localhost", 6666));

            socket.send(packet);
            if (data.equals("bye")) {
    
    
                break;
            }
        }
        socket.close();
    }
}

循环接收消息

package com.zhang.lession4;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

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
            byte[] data = packet.getData();
            String receiveData = new String(data, 0, data.length);
            System.out.println(receiveData);
            if (receiveData.equals("bye")) {
    
    
                break;
            }
        }
        socket.close();
    }
}

1.8、URL

http://www.baidu.com/

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

DNS域名解析 www.baidu.com

协议://ip地址:端口号/项目名/资源
package com.zhang.lession5;

import java.net.MalformedURLException;
import java.net.URL;

public class URLDemo01 {
    
    
    public static void main(String[] args) throws MalformedURLException {
    
    
        URL url = new URL("https://localhost:8080/helloworld/index.jsp?username=zhang&pwd=666");
        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.zhang.lession5;

import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class URLDownLoad {
    
    
    //http://localhost:8080/zhangtao/King/
    public static void main(String[] args) throws Exception {
    
    
        //1.下载地址
        URL url = new URL("http://localhost:8080/zhangtao/King/index.html");

        //2.连接到这个资源  HTTP
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

        //3.
        InputStream inputStream = urlConnection.getInputStream();
        FileOutputStream fos = new FileOutputStream("a.html");

        byte[] buffer = new byte[1024];
        int len;
        while ((len = inputStream.read(buffer)) != -1) {
    
    
            fos.write(buffer, 0, len);        //写出这个数据
        }
        fos.close();
        inputStream.close();
        urlConnection.disconnect();     //断开连接
    }
}

猜你喜欢

转载自blog.csdn.net/zhang_0202/article/details/114447269