Java_网络编程

2,017 阅读6分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

@[TOC]

网络编程

网络编程目的: 无线电接收,通信,连接数据交换 共享

网络通信的两大要素:

  1. 通信双方的IP地址+端口号
  2. 通信协议(FTP文件传输协议,SMTP发送邮件,TCP,UDP,HTTP)。实际上主要学习的是TCP/IP协议簇中传输层的TCP和UDP协议

一、通信双方的IP地址+端口号

1、IP地址

对于Java来说集中于InetAddress类包下:唯一定位一台网络上的计算机

IP地址:eg:127.0.0.1 196.168.0.1

IP分类:IPV4/IPV6、公网/私网

  • IPV4

    eg:127.0.0.1 4个字节32位组成,长度0-255

    IPV4的IP地址分类:

    IP地址由四段组成,地址长度为32位,共4个字节,每个字段是一个字节(Byte)即8位二进制,最大值是255。实际中我们用“点分十进制记法”。

    IP地址由两部分组成,即网络地址主机地址。网络地址表示其属于互联网的哪一个网络,主机地址表示其属于该网络中的哪一台主机。二者是主从关系。

在这里插入图片描述

A类:0.0.0.0-127.255.255,其中段0和127不可用

B类: 128.0.0.0-191.255.255.255 63

C类:192.0.0.0-223.255.255.255 31

D类: 224.0.0.0-239.255.255.255 15

  • IPV6

    查看本机IPV6地址命令:ipconfig

    本地链接 IPv6 地址. . . . . . . . : fe80::4cfb:8b05:9334:39d7%5		128位,8个无符号整数
    
  • 公网——互联网

  • 私网——也叫内网,有家庭局域网、校园网

import java.net.InetAddress;
import java.net.UnknownHostException;
public class ip地址 {
    public static void main(String[] args) throws UnknownHostException {
        //返回本地主机地址
        // .getByName("localhost"),.getByName("127.0.0.1")
        InetAddress ip = InetAddress.getByName("localhost");
        InetAddress ip_simple = InetAddress.getLocalHost();
        InetAddress ip1 = InetAddress.getByName("127.0.0.1");
        System.out.println("ip:"+ip);
        InetAddress ip2 = InetAddress.getByName("198.168.0.1");
        System.out.println("ip2:"+ip2);


        //查询网站地址
        InetAddress ip3 = InetAddress.getByName("www.baidu.com");
        System.out.println("ip3:"+ip3);


        //常用方法
        System.out.println(ip2.getCanonicalHostName());   //获取此IP地址的完全限定域名。String,198.168.0.1
        System.out.println(ip2.getHostAddress());       //返回文本显示中的IP地址字符串String,198.168.0.1
        System.out.println(ip2.hashCode());     	//返回此IP地址的哈希码。int,-962068479
        System.out.println(ip2.getAddress());       //返回此 InetAddress对象的原始IP地址。byte[],[B@49097b5d
        System.out.println(ip2.getHostName());      //获取此IP地址的主机名。String,198.168.0.1
    }
}
2、端口号

InetSocketAddress类下:端口表示计算机上一个程序的进程,不同进程有不同的端口号,范围0-65535

端口分类:共有端口、程序注册端口、动态私有端口

  • 共有端口  范围0-1023

    HTTP:80

    HTTPS:443

    FTP:21

    Telnet:23

  • 程序注册端口  范围1024-49151:分配给用户和进程使用

    Tomcat:8080

    MySQL:3306

    Oracle:1521

    IDEA:63342

  • 动态私有端口  范围49152-65535

可以用netstat -ano 查看全部端口连接情况

netstat -ano|findstr "端口号" 查看指定端口号的连接

import java.net.InetSocketAddress;

public class 端口号 {
    public static void main(String[] args) {
        InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1",8080);
        InetSocketAddress inetSocketAddress1 = new InetSocketAddress("localhost",8080);
        System.out.println("inetSocketAddress:" + inetSocketAddress);
        System.out.println("inetSocketAddress1" + inetSocketAddress1);

        System.out.println(inetSocketAddress.getAddress());     //返回此 InetAddress对象的原始IP地址。
        System.out.println(inetSocketAddress.getHostName());    //获取主机名,在.host文件中设置的
        System.out.println(inetSocketAddress.getPort());        //获取端口号
    }
}

二、通信协议

实际上主要学习的是TCP/IP协议簇中传输层的TCP和UDP协议

  • TCP:用户传输协议

    相当于打电话,面向连接的稳定的传输控制协议

    经典的三次握手四次挥手【请自行百度】

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

    //TCP实现聊天		服务器端;
    
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    /**
     * 服务器端等待客户端连接
     */
    public class server {
        public static void main(String[] args) throws IOException {
            //1.服务器先有地址端口号,ServerSocket
            //2.让客户端get
            ServerSocket serverSocket = new ServerSocket(9999);
    
            //等待客户端连接,accept
            Socket socket = serverSocket.accept();
    
            //读取客户信息,io
            InputStream is = socket.getInputStream();
            //读入流
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            while ((len=is.read(buffer)) != -1){
                byteArrayOutputStream.write(buffer,0,len);
            }
            System.out.println(byteArrayOutputStream.toString());
    
            //关闭流
            byteArrayOutputStream.close();
            is.close();
            socket.close();
            serverSocket.close();
        }
    }
    
//TCP实现聊天		客户端;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;

/**
 * 客户端主动发起连接,发送消息
 */
public class client {
    public static void main(String[] args) throws IOException {
        //1.客户端获取地址+端口号定位通信
        InetAddress ip = InetAddress.getByName("127.0.0.1");
        int port = 9999;

        //2.创建Socket连接
        Socket socket = new Socket(ip, port);

        //3.发送消息,io流
        OutputStream os = socket.getOutputStream();
        //发送流
        os.write("欢迎使用本公司智能语音小电!".getBytes());

        //4.关闭流
        os.close();
        socket.close();
    }
}


//TCP文件上传		服务器端;

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

public class server {
    public static void main(String[] args) throws IOException {
        //创建服务
        //监听等待客户端的连接
        //获取输入流
        //文件输出

        //创建服务
        ServerSocket serverSocket = new ServerSocket(9090);

        //等待客户端的连接
        Socket accept = serverSocket.accept();

        //获取输入流
        InputStream is = accept.getInputStream();

        //文件输出
        FileOutputStream fileOutputStream = new FileOutputStream(new File("ssl.jpg"));
        byte[] buffer = new byte[1024];
        int len;
        while ((len=is.read(buffer)) != -1){
            fileOutputStream.write(buffer,0,len);
        }

        //通知客户端,我已经接收完毕
        OutputStream os = accept.getOutputStream();
        os.write("我已经接收完毕,你可以断开了!".getBytes());

        //关闭资源
        os.close();
        fileOutputStream.close();
        is.close();
        accept.close();
        serverSocket.close();
    }
}
//TCP文件上传		客户端;

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


public class client {
    public static void main(String[] args) throws Exception {
        //创建socket连接
        //创建一个输入流
        //读取要输入的文件
        //写入文件
        //关闭资源

        //创建socket连接
        Socket socket = new Socket(InetAddress.getByName("196.168.0.1"), 9090);

        //创建一个输入流
        OutputStream os = socket.getOutputStream();

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

        //通知服务器,我已经结束了
        socket.shutdownOutput();
        //确定服务器也已经接收完毕,才断开连接
        InputStream inputStream = socket.getInputStream();
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buffer2 = new byte[2014];
        int len2;
        while ((len2=inputStream.read(buffer2)) != -1){
            byteArrayOutputStream.write(buffer2,0,len2);
        }
        System.out.println(byteArrayOutputStream.toString());

        //关闭资源
        fileInputStream.close();
        inputStream.close();
        byteArrayOutputStream.close();
        os.close();
        socket.close();
    }
}

  • UDP:用户数据报协议

    发短信,定位发送,不管实际有没有发送到

//UDP消息发送		server;

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


public class server_消息发送 {
    public static void main(String[] args) throws Exception {
        //1.开放端口,2.接收数据包

        //开放端口
        DatagramSocket socket = new DatagramSocket(7777);

        //接收数据报
        byte[] bytes = new byte[1024];
        DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length);
        socket.receive(packet);//阻塞接收,没有输出

        //输出
        System.out.println(packet.getAddress().getHostAddress());
        System.out.println(new String(packet.getData(),0,packet.getLength()));

        //关闭资源
        socket.close();
    }
}
//UDP消息发送		client;

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

public class client_消息发送 {
    public static void main(String[] args) throws Exception {
        //建立一个Socket
        //建立包
        //发送包

        //建立一个Socket
        DatagramSocket socket = new DatagramSocket();

        //建立包
        String msg = "hello message is sending!";
        InetAddress localhost = InetAddress.getByName("localhost");
        int port = 7777;
        DatagramPacket packet = new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,localhost,port);

        //发送包
        socket.send(packet);
        //关闭资源
        socket.close();
    }
}

另外

  • IP协议:网络互连协议

  • HTTP:超文本传输协议

  • HTTPS:比HTTP更安全

  • TELNET:远程控制协议

  • SMTP:邮件传输协议

  • FTP:文件传输协议

  • DHCP:动态主机配置协议

  • ICMP:消息控制协议

  • ARP:地址解析协议

在这里插入图片描述

三、URL

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

语法规则:一个网页地址实例: www.runoob.com/html/html-t…)

scheme://host.domain:port/path/filename

语法规则: 协议://主机:端口号/路径/文件名


//URL统一资源定位符;

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

public class URL_get {
    public static void main(String[] args) throws MalformedURLException {
        URL url = new URL("http://localhost:8080/helloworld/index.jsp?username=kuangshen&password=123");

        System.out.println(url.getProtocol());      //协议
        System.out.println(url.getPort());      //端口
        System.out.println(url.getPath());      //全路径
        System.out.println(url.getFile());      //文件
        System.out.println(url.getQuery());     //参数
        System.out.println(url.getHost());  //主机ip
    }
}

用URL爬音乐文件

//URL统一资源定位符;

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

public class 爬_音乐 {
    public static void main(String[] args) throws IOException {
        //1.给出地址
        URL url = new URL("https://m701.music.126.net/20210207215341/da14cf96e421aca600f13f6aa58469a7/jdyyaac/545f/540b/5552/c5469da843cab5958af5b89262a89c3a.m4a");

        //2.连接资源
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

        InputStream inputStream = urlConnection.getInputStream();
        FileOutputStream fileOutputStream = new FileOutputStream("castle.m4a");		//这里输出流命名.m4a        //3.流
        byte[] bytes = new byte[1024];
        int len;
        while ((len=inputStream.read(bytes)) != -1){
            fileOutputStream.write(bytes,0,len);
        }

        //4.关闭资源
        fileOutputStream.close();
        inputStream.close();
        urlConnection.disconnect();
    }
}