【Java 18】网络编程 - 概述、网络编程要素、IP和端口号、网络协议、TCP、UDP、URL

25 篇文章 0 订阅
20 篇文章 0 订阅

网络编程

image-20200902193546395

1 网络编程概述

image-20200902193649174

image-20200902193655798

  • 网络编程中有两个主要的问题:

    • 如何准确地定位网络上一台或多台主机;定位主机上的特定的应用
    • 找到主机后如何可靠高效地进行数据传输
  • 网络编程中的两个要素:

    • 对应问题一:IP和端口号
    • 对应问题二:网络通信协议:TCP/IP参考模型(应用层、传输层、网络层、物理+数据链路层)

2 网络通信要素概述

image-20200902193707141

image-20200902193714769

image-20200902193721360

3 通信要素1:IP和端口号

IP:Internet Protocol

3.1 内容

image-20200902193729487

image-20200902193735312

image-20200902193741129

通信要素一:IP和端口号

  • IP:唯一的标识 Internet 上的计算机(通信实体)

  • 在Java中使用InetAddress类代表IP

  • IP分类:IPv4 和 IPv6;万维网 和 局域网

  • 域名:www.baidu.com

  • 本地回路地址:127.0.0.1

    对应着:localhost

  • 如何实例化InetAddress(无构造器):

    • 两个获取InetAddress实例方法:
      • public static InetAddress getByName(String host)
      • public static InetAddress getLocalHost()
    • 两个常用方法:
      • public String getHostName():获取此 IP 地址的主机名【域名】
      • public String getHostAddress():返回 IP 地址字符串(以文本表现形式)【IP地址】
  • 端口号:正在计算机上运行的进程

    要求:不同进程有不同的端口号

    范围:被规定维一个16位的整数0~65535

  • 端口号与IP地址的组合得出一个网络套接字:Socket

3.2 InetAddress类

3.2.1 概述

image-20200902193750310

image-20200902193754856

3.2.2 方法

image-20200902193802436

3.2.3 代码实例

image-20200902193809116

public class InetAddressTest {

    public static void main(String[] args) {

        try {
            //File file = new File("hello.txt");
            InetAddress inet1 = InetAddress.getByName("192.168.10.14");
            System.out.println(inet1);

            InetAddress inet2 = InetAddress.getByName("www.wumiaojie.com");
            System.out.println(inet2);

            InetAddress inet3 = InetAddress.getByName("127.0.0.1");
            System.out.println(inet3);

            //获取本机IP
            InetAddress inet4 = InetAddress.getLocalHost();
            System.out.println(inet4);

            //getHostName()
            //获取此IP地址的主机名
            System.out.println(inet2.getHostName());

            //getHostAddress()
            //返回IP地址字符串
            System.out.println(inet2.getHostAddress());

        } catch (UnknownHostException e) {
            e.printStackTrace();
        }

    }

}

4 通信要素2:网络协议

4.1 内容

image-20200902193817196

4.2 TCP/IP协议簇

image-20200902193821425

4.3 TCP和UDP

image-20200902193829305

4.4 TCP三次握手和四次挥手

image-20200902193837418

  1. 三次握手

    客户端:你好,我是吴

    服务端:你好,我知道你是吴,我是王

    客户端:你好,我知道你知道我是吴,我是吴

  2. UDP:(可用于视频直播)

    导弹全部一次性多量发送,被拦截率低,不管有没有打中

image-20200902193848157

一般是客户端主动断开连接

客户端:我现在想断开连接了

服务端:我接受到你想断开连接的信息了

服务端:我现在已经断开连接了

客户端:发个信息确认是否断开【有没有后话,无则断开了】

4.5 Socket

端口号与IP地址的组合得出一个网络套接字:Socket

image-20200902193854944

image-20200902193903944

5 TCP网络编程

5.1 基于Socket的TCP编程

image-20200902193913536

image-20200902234329888

image-20200902234349504

image-20200902234358105

image-20200902234405254

5.2 代码实例

客户端岛

服务器岛

客户端岛生产了一些产品想卖给服务器岛

于是客户端岛整了一小船(Socket),船里装东西

船有运送的目的,即服务器岛(IP)

服务器岛有多个港口(ServerSocket),船要停在哪里,就需要只能具体的港口号码(端口号)

package com.wmiao.java;

import org.junit.Test;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @author wmiao
 * @version 1.0
 * @description: 实现TCP的网络编程
 * 客户端发送信息给服务端,服务端将数据显示在控制台上
 * @date 2020/9/3 0:02
 */

public class TCPTest1 {

    //客户端
    @Test
    public void client() {

        Socket socket = null;
        OutputStream os = null;
        try {
            //1.创建客户端的Socket对象,指明服务器端的ip和端口号
            InetAddress inet = InetAddress.getByName("127.0.0.1");
            socket = new Socket(inet, 8899);

            //2.获取一个输出流,用于输出数据
            os = socket.getOutputStream();

            //3.写出数据的操作
            os.write("你好啊".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4.资源的关闭
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    //服务器
    @Test
    public void server(){

        ServerSocket ss = null;
        Socket socket = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;
        try {
            //1.创建服务器端的ServerSocket对象,指明自己的端口号
            ss = new ServerSocket(8899);
            //2.调用accept(),表示接收崽子于客户端的socket
            socket = ss.accept();
            //3.获取输入流
            is = socket.getInputStream();

            //不建议这样写,可能有乱码
//        byte[] buffer = new byte[1024];
//        int len;
//        while ((len = is.read(buffer)) != -1){
//            String str = new String(buffer,0,len);
//            System.out.println(str);
//        }

            //4.读取输入流中的数据
            baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[5];
            int len;
            while ((len = is.read(buffer)) != -1){
                baos.write(buffer,0,len);//写到了ByteArrayOutputStream类里面的数组,不足会扩容
            }

            System.out.println(baos.toString());

            //获取客户端发送者信息
            //System.out.println("收到了来自于:" + socket.getInetAddress().getHostAddress() + "的数据");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //5.关闭资源
            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 (ss != null) {
                try {
                    ss.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

}

服务端获取客户端发送者信息

//获取客户端发送者信息
System.out.println("收到了来自于:" + socket.getInetAddress().getHostAddress() + "的数据");

5.3 例题

image-20200902234410693

package com.wmiao.java;

import org.junit.Test;

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

/**
 * @author wmiao
 * @version 1.0
 * @description: 例题2:客户端发送文件给服务端,服务端将文件保存在本地
 * @date 2020/9/3 1:26
 */

public class TCPTest2 {

    //客户端
    @Test
    public void client() {
        Socket socket = null;
        OutputStream os = null;
        FileInputStream fis = null;

        try {
            //1.创建客户端的Socket对象,指明服务器端的ip和端口号
            socket = new Socket(InetAddress.getByName("127.0.0.1"),8899);
            //2.获取一个输出流,用于输出数据
            os = socket.getOutputStream();

            //3.创建一个输入流对象,用于从硬盘读入文件到内存
            fis = new FileInputStream(new File("爱情与友情.jpg"));

            //4.文件读入操作 + 文件传输服务端操作
            byte[] buffer = new byte[20];
            int len;
            while ((len = fis.read(buffer)) != -1){
                os.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //5.资源的关闭
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    //服务器
    @Test
    public void server(){
        ServerSocket ss = null;
        Socket socket = null;
        InputStream is = null;
        FileOutputStream fos = null;

        try {
            //1.创建服务器端的ServerSocket对象,指明自己的端口号
            ss = new ServerSocket(8899);
            //2.调用accept(),表示接收崽子于客户端的socket
            socket = ss.accept();
            //3.获取输入流
            is = socket.getInputStream();

            //4.创建一个输出流,用于从内存将文件保存到硬盘
            fos = new FileOutputStream(new File("爱情与友情1.jpg"));

            //5.读取输入流中的数据 + 将数据通过FileOutputStream流保存到硬盘
            byte[] buffer = new byte[20];
            int len;
            while ((len = is.read(buffer)) != -1){
                fos.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //6.资源的关闭
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (ss != null) {
                try {
                    ss.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


    }

}
package com.wmiao.java;

import org.junit.Test;

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

/**
 * @author wmiao
 * @version 1.0
 * @description: 例题三:从客户端发送文件给服务端,服务端保存到本地。并返回“发送成功”给
 * 客户端。并关闭相应的连接
 * @date 2020/9/3 2:10
 */

public class TCPTest3 {

    //客户端
    @Test
    public void client() {
        Socket socket = null;
        OutputStream os = null;
        FileInputStream fis = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;

        try {
            //1.创建客户端的Socket对象,指明服务器端的ip和端口号
            socket = new Socket(InetAddress.getByName("127.0.0.1"),8899);
            //2.获取一个输出流,用于输出数据
            os = socket.getOutputStream();

            //3.创建一个输入流对象,用于从硬盘读入文件到内存
            fis = new FileInputStream(new File("爱情与友情.jpg"));

            //4.文件读入操作 + 文件传输服务端操作
            byte[] buffer = new byte[20];
            int len;
            while ((len = fis.read(buffer)) != -1){
                os.write(buffer,0,len);
            }

            /*
            重要:这里要告诉服务器端传输数据结束的指示
            socket.shutdownOutput();
            */
            //关闭数据的输出
            socket.shutdownOutput();

            //5.客户端接收服务器端的反馈:“发送成功”
            // 接受来自于服务器端的数据,并显示到控制台上
            is = socket.getInputStream();

            baos = new ByteArrayOutputStream();
            byte[] buffer2 = new byte[20];
            int len2;
            while ((len2 = is.read(buffer2)) != -1){
                baos.write(buffer2,0,len2);
            }

            System.out.println(baos.toString());

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //6.资源的关闭
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (baos != null) {
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    //服务器
    @Test
    public void server(){
        ServerSocket ss = null;
        Socket socket = null;
        InputStream is = null;
        FileOutputStream fos = null;
        OutputStream os = null;

        try {
            //1.创建服务器端的ServerSocket对象,指明自己的端口号
            ss = new ServerSocket(8899);
            //2.调用accept(),表示接收崽子于客户端的socket
            socket = ss.accept();
            //3.获取输入流
            is = socket.getInputStream();

            //4.创建一个输出流,用于从内存将文件保存到硬盘
            fos = new FileOutputStream(new File("爱情与友情3.jpg"));

            //5.读取输入流中的数据 + 将数据通过FileOutputStream流保存到硬盘
            byte[] buffer = new byte[20];
            int len;
            while ((len = is.read(buffer)) != -1){
                fos.write(buffer,0,len);

                /*
                重要:is.read(buffer)是一个阻塞式的方法【没有明确告诉我,我就不会退出循环】
                 */

            }

            //6.服务器端给客户端反馈:“发送成功”
            os = socket.getOutputStream();
            os.write("你好,图片我已经收到,发送成功".getBytes());

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //7.资源的关闭
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (ss != null) {
                try {
                    ss.close();
                } 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();
                }
            }
        }


    }
}

image-20200902234437616

5.4 练习

image-20200902234442887

image-20200902234641583

6 UDP网络编程

6.1 内容

image-20200902234655895

6.2 常用方法

image-20200902234701362

image-20200902234707443

6.3 代码实例

image-20200902234712494

image-20200902234717364

image-20200902234726270

package com.wmiao.java;

import org.junit.Test;

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

/**
 * @author wmiao
 * @version 1.0
 * @description: TODO
 * @date 2020/9/3 2:52
 */

public class UDPTest {

    //发送端
    @Test
    public void sender(){

        DatagramSocket socket = null;
        try {
            socket = new DatagramSocket();

            String str = "我是UDP方式发送的导弹";
            byte[] data = str.getBytes();
            InetAddress inet = InetAddress.getLocalHost();
            DatagramPacket packet = new DatagramPacket(data,0,data.length,inet,8899);

            socket.send(packet);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (socket != null) {
                socket.close();
            }
        }

    }

    //接收端
    @Test
    public void receiver(){

        DatagramSocket socket = null;
        try {
            socket = new DatagramSocket(8899);

            byte[] buffer = new byte[100];
            DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);

            socket.receive(packet);

            System.out.println(new String(packet.getData(), 0, packet.getLength()));
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (socket != null) {
                socket.close();
            }
        }

    }

}

7 URL编程

7.1 URL类内容

image-20200902234743519

7.2 URL类构造器

image-20200902234751276

image-20200902234801922

7.3 URL类常用方法

image-20200902234810432

image-20200902234818452

7.6 代码实例

package com.wmiao.java;

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

/**
 * @author wmiao
 * @version 1.0
 * @description: TODO
 * @date 2020/9/3 3:17
 */

public class URLTest {
    public static void main(String[] args) {

        try {
            URL url = new URL("http://192.168.1.100:8080/helloworld/index.jsp#a?username=shkstart&password=123");

            //public String getProtocol( ) 获取该URL的协议名
            System.out.println("getProtocol() :"+url.getProtocol());
            //public String getHost( ) 获取该URL的主机名
            System.out.println("getHost() :"+url.getHost());
            //public String getPort( ) 获取该URL的端口号
            System.out.println("getPort() :"+url.getPort());
            //public String getPath( ) 获取该URL的文件路径
            System.out.println("getPath() :"+url.getPath());
            //public String getFile( ) 获取该URL的文件名
            System.out.println("getFile() :"+url.getFile());
            //public String getQuery( ) 获取该URL的查询名
            System.out.println("getQuery() :"+url.getQuery());

        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

    }
}

7.5 针对HTTP协议的URLConnection类

image-20200902234823687

image-20200902234829326

package com.wmiao.java;

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

/**
 * @author 吴淼杰
 * @version 1.0
 * @description: TODO
 * @date 2020/9/3 3:32
 */

public class URLTest1 {
    public static void main(String[] args) {

        HttpURLConnection urlConnection = null;
        InputStream is = null;
        FileOutputStream fos = null;
        try {
            URL url = new URL("http://localhost:8080/examples/beauty.jpg");

            urlConnection = (HttpURLConnection) url.openConnection();

            urlConnection.connect();

            is = urlConnection.getInputStream();
            fos = new FileOutputStream("day10\\beaty.jpg");

            byte[] buffer = new byte[1024];
            int len;
            while ((len = is.read(buffer)) != -1){
                fos.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
        }

    }
}

7.6 URI、URL和URN的区别

image-20200902234834671

8 小结

image-20200902234840019

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值