网络编程

网络编程

概述

  • 包(Package)

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

  • 网络编程的目的
    无线电台--传播交流信息,数据交换,通信

-需要做什么
如何准确定位网络上的一台主机 192.168.16.124:Port,定位到这个计算机上的某个资源;
如何传输数据,

网络编程: TCP/IP C/S
网页编程: javaWeb B/S

  • 网络通信的要素
    • 通信双方的地址
      • ip
      • 端口号
    • 规则(网络通信协议)
      • HTTP
      • FTP

IP地址(InetAddress)

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

  • 127.0.0.1:本机localhost

  • IP地址的分类:
    ipv4: 127.0.0.1,四个字节组成,0-255,42亿,30亿在北美,亚洲4亿,2011年用尽;
    ipv6:128位,8个无符号整数,用冒号分开;

  • 公网(互联网)/私网(局域网)
    ABCD类地址
    192.168.xx.xx,专门给组织内部使用

  • 域名:解决IP记忆问题
    IP:www.jd.com

/**
 * InetAddress
 */
public class N01IP {
    public static void main(String[] args) {
        try {
            //查询本机地址
            InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
            System.out.println(inetAddress);//127.0.0.1
            inetAddress = InetAddress.getByName("localhost");
            System.out.println(inetAddress);//localhost/127.0.0.1
            inetAddress = InetAddress.getLocalHost();
            System.out.println(inetAddress);//Lenovo-PC/10.136.64.127
            //查询网站ip地址
            inetAddress = InetAddress.getByName("www.baidu.com");
            System.out.println(inetAddress);//www.baidu.com/110.242.68.3
            //常用方法
            System.out.println(inetAddress.getAddress());//[B@b1bc7ed
            System.out.println(inetAddress.getCanonicalHostName());//110.242.68.3获得规范名字
            System.out.println(inetAddress.getHostAddress());//110.242.68.3
            System.out.println(inetAddress.getHostName());//www.baidu.com
        }catch (Exception e){
           e.printStackTrace();
        }
    }
}

端口(Port)

  • 表示计算机上的一个程序的进程;
  • 不同的进程有不同的端口号,用来区分软件;
  • 单个协议下,端口号不能冲突;
  • 端口被规定0~65536,TCP,UDP分别使用;
  • 端口分类:
    • 公有端口 0~1023
      • HTTP:80
      • HTTPS: 443
      • FTP: 21
      • Telent: 23
    • 程序注册端口 1024~49151
      • Tomcat 8080;
      • MysSQL 3306
      • Oracle 1521
    • 动态、私有 49152~65535
netstat -nao #查询所有的端口
netstat -nao|findstr "5900" #查看指定的端口
tasklist|findstr "8696" #查看指定端口的进程
ctrl+shift+esc #打开任务管理器 
/**
 * InetSocketAddress
 */
public class N02InetSocketAddress {
    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);// /127.0.0.1:8080
        System.out.println(socketAddress2);// localhost/127.0.0.1:8080

        System.out.println(socketAddress1.getAddress());// /127.0.0.1
        System.out.println(socketAddress1.getHostName());// 127.0.0.1
        System.out.println(socketAddress1.getPort());// 8080
    }
}

通信协议

协议:约定,好比普通话/英语
网络通讯协议:速率、传输码率、代码结构、传输控制...
TCP/IP协议族,实际上是一组协议
TCP:用户传输协议,打电话;
UDP: 用户数据报协议,发短信;
IP: 网络互联协议

TCP与UDP对比
TCP
连接、稳定;
三次握手,四次挥手;
客户端、服务端;
传输完成,释放连接,效率低
UDP
不连接,不稳定;
客户端、服务端没有严格的界限;
只管发,不管收;
DDOS:洪水攻击/饱和攻击

TCP(Transmission Control Protocol 传输控制协议)

客户端
1.连接服务器Socket;
2.发送消息;
服务器
1.建立服务的端口ServerSocket;
2.等待用户的连接accept();
3.接受用户的消息;

/**
 * TcpClient
 * 【注意】每次要先启动服务器端,后启动客户端!
 */
public class N03TcpClient {
    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("hello!".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();
                }
            }
        }
    }
}
/**
 * TcpServer
 */
public class N03TcpServer {
    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.等待客户端连接
            socket = serverSocket.accept();
            //3.读取客户端的消息
            is = socket.getInputStream();
            /*
            byte[] buffer = new byte[1024];
            int len;
            while ((len=is.read(buffer))!=-1){
                String msg = new String(buffer, 0, len);
                System.out.println(msg);
            }
             */
            //管道流
            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();
                }
            }
        }
    }
}

【注意】每次要先启动服务器端,后启动客户端!

/**
 * 文件上传客户端 
 * 【注意】要上传的文件需存在工程项目目录下,相对路径
 */
public class N04TcpFileUpClient {
    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();
        //3.读取文件
        //相对路径,存在工程目录下
        FileInputStream fis = new FileInputStream(new File("sun.jpg"));
        //4.写出文件
        byte[] buffer=new byte[1024];
        int length;
        while ((length=fis.read(buffer))!=-1){
            os.write(buffer,0,length);
        }
        //通知服务器,传输完毕
        socket.shutdownOutput();//传输完毕
        //确定服务器接受完毕,才能够断开
        InputStream is = socket.getInputStream();
        //String byte[]
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        while ((length=is.read(buffer))!=-1){
            baos.write(buffer,0,length);
        }
        System.out.println(baos.toString());
        //5.关闭资源
        baos.close();
        is.close();
        fis.close();
        os.close();
        socket.close();
    }
}
/**
 * 上传文件服务器
 */
public class N04TcpFileUpServer {
    public static void main(String[] args) throws Exception {
        //1.创建服务
        ServerSocket serverSocket = new ServerSocket(9000);
        //2.监听客户端连接
        Socket socket = serverSocket.accept();
        //3.获取输入流
        InputStream is = socket.getInputStream();
        //4.文件输出
        FileOutputStream fos=new FileOutputStream("upload.jpg");
        byte[] bufferOut = new byte[1024];
        int length;
        while ((length=is.read(bufferOut))!=-1){
            fos.write(bufferOut,0,length);
        }
        //通知客户端我接受完毕了
        OutputStream os=socket.getOutputStream();
        os.write("finish!".getBytes());
        //5.关闭资源
        fos.close();
        is.close();
        socket.close();
        serverSocket.close();
    }
}

模拟对话案例

/**
 * UDP 对话案例
 * 多线程:发送线程
 */
public class TalkSend implements Runnable{
    DatagramSocket socket = null;//数据接口
    BufferedReader reader = null;//字符流
    private String toIP;//发送到哪个IP
    private int toPort;//发送到哪个端口
    private int fromPort;//从哪个端口发送
    public TalkSend(int fromPort,String toIP,int toPort){
        this.fromPort=fromPort;
        this.toIP=toIP;
        this.toPort=toPort;
        try {
            socket = new DatagramSocket(this.fromPort);
            reader = new BufferedReader(new InputStreamReader(System.in));
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void run() {
        while (true){
            try {
                String data = reader.readLine();
                byte[] datas = data.getBytes();
                if (data.equals("bye")) {
                    break;
                }
                //数据,数据长度起始,要发送给谁
                DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress(this.toIP,this.toPort));
                //3.发送包
                socket.send(packet);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        //4.关闭
        socket.close();
    }
}
/**
 * UDP 对话案例
 * 多线程:接收线程
 */
public class TalkReceive implements Runnable{
    DatagramSocket socket=null;
    private int port;//接收端口号
    private String fromIP;//数据包来自哪个端口
    //构造函数,初始化
    public TalkReceive(int port){
        this.port=port;
        try {
            socket = new DatagramSocket(this.port);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void run() {
        while (true) {
            try {
                //2.接收数据包
                byte[] buffer = new byte[1024];
                DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
                socket.receive(packet); //阻塞式接收包裹
                fromIP=packet.getSocketAddress().toString();
                //如果接收的数据时bye,断开连接
                String receiveData = new String(packet.getData(), 0, packet.getData().length);
                if (receiveData.equals("bye")) {
                    break;
                }
                System.out.println(fromIP+": "+receiveData);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        //3.关闭流
        socket.close();
    }
}
/**
 * UDP 对话案例 A角
 * 多线程:发送、接收
 */
public class TalkA {
    public static void main(String[] args) {
        new Thread(new TalkSend(8888,"localhost",9999)).start();
        new Thread(new TalkReceive(7777)).start();
    }
}
/**
 * UDP 对话案例 B角
 * 多线程:发送、接收
 */
public class TalkB {
    public static void main(String[] args) {
        new Thread(new TalkSend(6666,"localhost",7777)).start();
        new Thread(new TalkReceive(9999)).start();
    }
}

【注意】接收端口和发送端口要匹配

URL(Uniform Resource Locator)

  • URL
    是URI的一个子集。它是Uniform Resource Locator的缩写,译为“统一资源定位 符”;
    通俗地说,URL是Internet上描述信息资源的字符串,主要用在各种WWW客户程序和服务器程序上;
    采用URL可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等。URL是URI概念的一种实现方式;

URL的一般格式为(带方括号[]的为可选项):
protocol 😕/ hostname[:port] / path / [;parameters][?query]#fragment

URL的格式由三部分组成:
①第一部分是协议(或称为服务方式);
②第二部分是存有该资源的主机IP地址(有时也包括端口号);
③第三部分是主机资源的具体地址,如目录和文件名等;
第一部分和第二部分用“😕/”符号隔开;
第二部分和第三部分用“/”符号隔开;
第一部分和第二部分是不可缺少的,第三部分有时可以省略;

  • URI
    <1>什么是URI
    统一资源标志符(Uniform Resource Identifier, URI),表示的是web上每一种可用的资源,如 HTML文档、图像、视频片段、程序等都由一个URI进行标识的。

<2>URI的结构组成,通常由三部分组成:
①资源的命名机制;
②存放资源的主机名;
③资源自身的名称。
【注意】这只是一般URI资源的命名方式,只要是可以唯一标识资源的都被称为URI,上面三条合在一起是URI的充分不必要条件)

<3>URI举例https://blog.csdn.net/qq_32595453/article/details/79516787

我们可以这样解释它:
①这是一个可以通过https协议访问的资源;
②位于主机 blog.csdn.net上;
③通过“/qq_32595453/article/details/79516787”可以对该资源进行唯一标识(注意,这个不一定是完整的路径);
【注意】以上三点只不过是对实例的解释,以上三点并不是URI的必要条件,URI只是一种概念,怎样实现无所谓,只要它唯一标识一个资源就可以了。

  • URI和URL之间的区别
    从上面的例子来看,你可能觉得URI和URL可能是相同的概念,其实并不是,URI和URL都定义了资源是什么,但URL还定义了该如何访问资源。URL是一种具体的URI,它是URI的一个子集,它不仅唯一标识资源,而且还提供了定位该资源的信息。URI 是一种语义上的抽象概念,可以是绝对的,也可以是相对的,而URL则必须提供足够的信息来定位,是绝对的。
/**
 * URL 函数
 * 文件下载
 */
public class URLDemo {
    URL url=null;
    public void init() throws MalformedURLException {
        //网易云音乐下载歌曲
        url=new URL("https://m801.music.126.net/20220403125636/8af36ae46480d00c2741140a9b75b90c/jdyyaac/obj/w5rDlsOJwrLDjj7CmsOj/13739329659/1cde/fb40/a012/9ab88dd215324a760f39026ebbe4e295.m4a");
        //百度下载图片
//        url=new URL("https://t7.baidu.com/it/u=963301259,1982396977&fm=193&f=GIF");
        System.out.println(url.getProtocol());//协议 http
        System.out.println(url.getHost());//主机ip localhost
        System.out.println(url.getPort());//端口 8080
        System.out.println(url.getPath());//文件全路径 /hello/index.jsp
        System.out.println(url.getQuery());//参数 name=zs&psd=123
    }
    public void downLoad() throws IOException {
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
        InputStream is = urlConnection.getInputStream();
        FileOutputStream fos = new FileOutputStream("music.m4a");
//        FileOutputStream fos = new FileOutputStream("风景.jpg");        
        byte[] buffer=new byte[1024];
        int length;
        while ((length=is.read(buffer))!=-1){
            fos.write(buffer,0,length);
        }
    }
    public static void main(String[] args) throws Exception {
        URLDemo urlDemo=new URLDemo();
        urlDemo.init();
        urlDemo.downLoad();
    }
}
posted @ 2022-03-30 16:48  老李学Java  阅读(55)  评论(0)    收藏  举报