网络编程笔记

网络编程

InetAddress  	 获取地址
InetAddress.getCanonicalHostName		规范的名字
InetAddress.getHostAddress		IP
InetAddress.getHostName		域名或自己电脑的名字
InetSocketAddress		实现 IP 地址及端口
InetAddress				实现 IP 地址
ServerSocket				建立服务的端口
.accept						阻塞监听等待连接
Socket						创建连接
.getInputStream				获取IO输入流
.getOutputStream			获取IO输出流
ByteArrayOutputStream		byte类型数组管道输出流
FileOutputStream		文件字符输出流
FileInputStream			文件字符输入流
shutdownOutput			停止输出
DatagramSocket			数据包端口
DatagramPacket			数据包
.send			发送
.receive		阻塞接收
BufferedReader			缓存区读取
InputStreamReader		输入流读取
.readLine				读取的一行内容
URL			统一资源定位符
.openConnection				打开连接
HttpURLConnection			指定协议HTTP

1.1、计算机网络概念

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

网络编程的目的
  传播交流信息
  数据交换、通信。

想要达到这个效果,需要什么
  1.如何准确的定位网络上的一台主机 192.168.1.100: 端口,定位到这个计算机上的某个资源。
  2.找到了这个主机,如何传输数据呢?

JavaWeb : 网页编程 B/S架构
网络编程: TCP/IP C/S架构

1.2网络通信要素

如何实现网络的通信?
  通信双方的地址:
    IP、端口号。
    192.168.1.100:8080

规则:网络通信的协议

http, ftp, smtp, tcp,udp…

TCP/IP参考模型

在这里插入图片描述

小结:
  1.网络编程中两个主要问题
    如何准确定位到网络上的一台或多台主机
    找到主机之后如何进行通信

2.网络编程中的要素
    IP 和 端口号
    网络通信协议

3.Java 万物皆对象

1.3、IP

ip地址:InetAddress

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

  • 127.0.0.1:本机Iocalhost

  • ip地址的分类

    ipv4/ipv6

IPV4:127.0.0.1 ,4个字节组成,0~255,总共42亿;30亿都在北美,亚洲4亿,2011年就已经用尽
IPV6:128位。8个无符号整数。2001:acca:0ac1:0002:0ab7:1153:2210:ccc1
公网(互联网)-私网(局域网)

ABCD类地址

192.168.xxx.xx 专门给组织内部使用

域名:记忆IP问题

IP:www.xxx.com 方便记录

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(Arrays.toString(inetAddress2.getAddress()));      //返回一个数组
            System.out.println(inetAddress2.getCanonicalHostName());        //规范的名字
            System.out.println(inetAddress2.getHostAddress());      //ip
            System.out.println(inetAddress2.getHostName());     //域名,或者自己电脑的名字

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
InetAddress  	 获取地址
InetAddress.getCanonicalHostName		规范的名字
InetAddress.getHostAddress		IP
InetAddress.getHostName		域名或自己电脑的名字
1.4、端口

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

不同的进程有不同的端口!用来区分软件!

被规定0~65535,不能使用相同的端口

TCP,UDP:65535*2,tcp : 80, udp : 80 这样不影响。单个协议下,端口号不能冲突

端口分类

1.公有端口 0~1023 (尽量不用)

  • HTTP:80

  • HTTPS:443

  • FTP:21

  • Telent:23

    2.程序注册端口:1024~49151,分配用户或者程序

  • Tomcat:8080

  • MySQL:3306

  • Oracle:1521

    3.动态、私有:49152~65535(尽量不用)

    netstat -ano   #查看所有的端口
    netstat -ano|findstr "5900"  #查看指定的端口
    tasklist|findstr "12296"    #查看指定端口的进程【这是我的QQ端口ID】
    
    //端口
    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());        //端口
    
        }
    }
    
    • 找到电脑上特定端口,或有其对应的处理程序,才能收到发出的程序
InetSocketAddress		 IP 地址及端口
InetAddress				 IP 地址
1.5、通信协议

协议:约定,双方使用相同可识别的语言

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

主要使用:TCP/IP协议簇:实际上是一组协议

主要:

  • TCP:用户传输协议 {类似于打电话,需要两边进行连接}
  • UDP:用户数据报协议 {类似于发短信,不需要两边连接也可以发出,但不一定能送到}

出名的协议:

  • TCP:
  • IP:网络互连协议

TCP UDP 对比

TCP:打电话

  • 连接、稳定
  • 三次握手 四次挥手
最少需要三次,保证稳定连接
A——	我要连接 ——>B
B—— 你可以连接 ——>A
A—— 那我连接了 ——>B
连接成功!

四次挥手
A——我要断开——>B
B——你可以断开——>A

B——你确定断开?——>A
A——我确定断开!——>B
连接断开
  • 客户端、服务端:主动和被动的过程
  • 传输完成,释放连接,效率低

UDP:发短信

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

服务器

  1. 建立服务的端口 ServerSocket
  2. 等待用户的连接 accept
  3. 接收用户的信息

服务端

//服务端
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);
            int i = 0;
            while (true){
                //2.等待客户端连接过来
                System.out.println("等待客户端连接");
                socket = serverSocket.accept();
                //3.读取客户端的信息
                i++;
                is =socket.getInputStream();
                System.out.println("读取信息成功"+i);
                baos = new ByteArrayOutputStream();
                //创建一个接收数据的byte[]数组,及数组的有效长度len
                byte[] buffer = new byte[1024];
                int len;
                while ((len=is.read(buffer))!=-1){
                    baos.write(buffer,0,len);
                }
                System.out.println(baos.toString());
            }
        }
           /*//一种方法
           //创建一个接收数据的byte[]数组,及数组的有效长度len
            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();
                }
            }
        }
    }
}

客户端

  1. 连接服务器 Socket
  2. 发送消息
//客户端
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;
            System.out.println("客户端连接成功");
            //2.创建一个 socket 连接
            socket = new Socket(serverIP,port);
            //3.发送消息 IO 流
            os = socket.getOutputStream();
            os.write("你好,欢迎学习狂神说Java".getBytes());
            System.out.println("已发送");
        } catch (IOException e) {
            e.printStackTrace();
        }
        //保证代码的严谨性
        if (socket!= null){try {
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }}
        if (os!=null){try {
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        }}
    }
}

文件上传

服务器端

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

    }
}

客户端

public class TcpClientDemo02 {
    public static void main(String[] args) throws Exception {
        //1.创建一个Socket连接
        // Socket(主机--端口号)
        //InetAddress.getByNam(主机--IP地址)
        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000);
        //2.创建一个输出流
        OutputStream os = socket.getOutputStream();
        //3.读取文件
        FileInputStream fis = new FileInputStream(new File("tb.png"));
        //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();
        //由于收到的式String byte[]数组,使用byte输出管道流
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer2 = new byte[1024];
        int len2;
        while((len2 = inputStream.read(buffer))!=-1){
            baos.write(buffer,0,len2);
        }
        System.out.println(baos.toString());

        //关闭资源
        baos.close();
        inputStream.close();
        fis.close();
        os.close();
        socket.close();
    }
}
FileOutputStream		文件输出流
FileInputStream			文件输入流
shutdownOutput			停止输出
Tomcat

服务端

  • 自定义 S
  • Tomcat 服务器 S :Java 后台开发!

客户端

  • 自定义 C
  • 浏览器 B
1.7、DUP

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

发生消息

发送端

public class UdpClientDemo01 {
    public static void main(String[] args) throws Exception {
        //1.建立一个socket
        DatagramSocket socket = new DatagramSocket(8080);
        //1.2建立一个能发送的包
        //发送的数据,地址
        String msg = "你好啊,服务器!";
        InetAddress localhost = InetAddress.getByName("localhost");
        int port = 9090;
        //包的内容:数据,数据长度,要发送给谁
        DatagramPacket packet = new DatagramPacket(msg.getBytes(),0,msg.getBytes().length,localhost,port);
        //2.发送包
        socket.send(packet);
        //关闭流
        socket.close();
    }
}

接收端

public class UdpServerDemo02 {
    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(packet.getAddress().getHostAddress());
        System.out.println(new String(packet.getData(),0,packet.getLength()));

        //关闭流
        socket.close();

    }
}

两端可以相互发送消息

DatagramSocket		数据包端口
DatagramPacket		数据包
.send			    发送
.receive		    阻塞接收

持续发送

持续发送端

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[] 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();
    }
}

持续接收端

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);
            //断开连接
            //将接收包转换为 String 格式
            byte[] data = packet.getData();
            String receiveData = new String(data,0,data.length);
            System.out.println(receiveData);

            if (receiveData.equals("bye")){
                break;
            }
        }
        socket.close();
    }
}
BufferedReader			缓存区读取
InputStreamReader		输入流读取
.readLine				读取的一行内容

多线程发送

发送线程

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);
        } catch (SocketException e) {
            e.printStackTrace();
        }


    }

    @Override
    public void run() {

        try {
            while(true){
                //准备数据:控制台读取 System.in
                BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
                //发包内数据
                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();
    }
}

接收线程

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() {
        try {
            while(true){
                //准备接收包裹
                byte[] container = new byte[1024];
                DatagramPacket packet = new DatagramPacket(container,0,container.length);
                //阻塞式接收
                socket.receive(packet);
                //断开连接
                //将接收包转换为 String 格式
                byte[] data = packet.getData();
                String receiveData = new String(data,0,data.length);
                System.out.println(msgfrom+":"+receiveData);
                if (receiveData.equals("bye")){
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        socket.close();
    }
}

学生线程

public class TalkStudent {
    public static void main(String[] args) {
        //学生同时开启两个线程
        //学生自己的发送端口、接收IP、接收端口
        new Thread(new TalkSend(6666,"localhost",9999)).start();
        //学生自己接收端口、发送过来者
        new Thread(new TalkReceive(8888,"老师")).start();
    }
}

教师线程

 */
public class TalkTeacher {
    public static void main(String[] args) {
        //老师
        //老师自己的发送端口、接收IP、接收端口
        new Thread(new TalkSend(7777,"localhost",8888)).start();
        //老师自己接收端口、发送过来者
        new Thread(new TalkReceive(9999,"学生")).start();
    }
}
1.8、URL
https://www.baidu.com/

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

DNS 域名解析:www.baidu.com == xxx.x…x…x 的IP号

协议:(https) //ip地址:端口/项目名/资源

URL常用方法

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

        //协议http
        System.out.println(url.getProtocol());
        //主机ip,localhost
        System.out.println(url.getHost());
        //端口,8080
        System.out.println(url.getPort());
        //文件,/helloworld/index.jsp
        System.out.println(url.getPath());
        //全路径,/helloworld/index.jsp?username=kuangshen&password==123
        System.out.println(url.getFile());
        //参数,username=kuangshen&password==123
        System.out.println(url.getQuery());
    }
}

URL网络下载

public class UrlDown {
    public static void main(String[] args) throws Exception {
        //1.下载地址【这是一个真实的网络地址】
        URL url = new URL("https://music.163.com/#/song?id=1880886636");

        //2.连接到这个资源 HTTP
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
        //3.输入流
        InputStream inputStream = urlConnection.getInputStream();
        //4.下载到存放地址
        FileOutputStream fos = new FileOutputStream("gequ.m4a");
        //5.写出数据
        byte[] buffer = new byte[1024];
        int len ;
        while((len = inputStream.read(buffer))!=-1){
            fos.write(buffer,0,len);
        }
        fos.close();
        inputStream.close();
        urlConnection.disconnect(); //断开连接

    }
}
URL			统一资源定位符
.openConnection				打开连接
HttpURLConnection			指定协议HTTP
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序栾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值