【Java_Senior】七、Web基础网络编程(TCP\UDP)

Web网络编程

网络编程就是利用Java提供的API实现在不同计算机上的信息交换。
其要解决两个问题:

  1. 如何准确定位一台计算机和其中的进程
  2. 如何实现高效稳定的数据传输

网络编程的要素

IP、端口号

IP是计算机在网络中的唯一地址,用于在网络中定位计算机的位置。
端口号是计算机中进程的位置,用来定位是计算机中的哪个进程需要进行网络通信。
网络通过IP和端口号来确定一台计算机中的具体进程。

TCP\IP结构,网络通过TCP\IP结构来具体实现高效稳定的信息传输。

IP与端口号

定义

一个InetAddress类的对象就代表一个IP地址
计算机中每个进程都有一个对应的端口号,用来确定通信的地址

一个IP唯一的对应互联网上的一台主机,分为IPv4地址与IPv6地址
也分为公网IP地址与局域网IP地址(公网IP地址就是大家可以在外面看到的地址)一般192.168.0.0~192.168.255.255为私有局域网的IP地址

使用域名访问网站的过程:
访问域名->域名被发送到DNS解析服务器->由DNS解析服务器解析出域名所对应的公网IP地址->由网络服务器访问公网IP地址来实现访问网站的功能。

本地地址:127.0.0.1,或者写成localhost

端口号:规定端口号为一个2的16次方即0-65535的数,其中:
公认端口:0~1023被用作通信服务(HTTP占用端口号80,FTP占用21,Telnet占用23)
注册端口:1024~49151被用作进程或应用程序(Tocat占用8080,MySQL占用3306,Oracle占用1521)
动态/私有端口:49152~65535

端口号和IP地址的组合形成一个网络套接字:Socket

方法

//实例化IP对象的方法
.getByName();   //获取网络上的IP对象。
.getByLocalHost(); //获取本机的IP对象。

举例实践

    public static void main(String[] args) throws UnknownHostException {
        InetAddress ina = InetAddress.getByName("47.93.172.3");
        System.out.println(ina);

        InetAddress ina1 = InetAddress.getByName("www.baidu.com");
        System.out.println(ina1);

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

        InetAddress ina3 = InetAddress.getLocalHost();
        System.out.println(ina3);
    }
//输出:
/47.93.172.3
www.baidu.com/220.181.38.150
/127.0.0.1
DESKTOP-MTFRJRE/192.168.1.2

网络协议

定义

传输层协议:TCP、UDP
TCP:

  1. TCP协议使用前必须建立TCP连接形成数据通路。
  2. 传输前进行三次握手保证数据通路的点对点通信可靠性
  3. TCP中进行通信的两个端:客户端、服务端
  4. 在连接中可以进行大量的的数据传输
  5. 传输完毕时释放已建立的连接,效率低。

UDP:

  1. 将目的、数据、源封装成数据包,其不需要建立连接
  2. 每个数据包的大小限制在64K之内
  3. 不管对方是否准备好,接收方也不需要发送确认帧,是不可靠的传输
  4. 可以广播发送
  5. 数据发送结束时无需释放资源,开销小,速度快。

UDP使用DatagramSocket和DatagramPocket实现基于UDP的网络协议。
UDP使用DatagraSocket发送和接收,系统不保证能否顺利抵达,也不保证何时抵达。
DatagramPocket封装了UDP的数据报,其中包括发送端的IP和端口号以及接收端的IP和端口号。
UDP协议中每个数据报都有发送端和接收端的信息,因此也无需再建立稳定连接。

TCP三次握手(建立连接)
客户端发送:seq=x,SYN=1(代表我期待收到x+1的确认帧,我的标识为1)
服务器端发送:SYN=1,seq=y,ACK=x+1(代表我发送给你x+1供你确认,确认你的标识是1,我期待收到y+1的确认)
客户端发送:ACK=y+1,seq=x+1(代表我发送y+1供你确认,我期待收到x+2的确认)

TCP四次挥手(断开连接)


URL
URL是指唯一定位网络资源的地址。其格式为:
<传输协议>://<主机名>:<端口号>/<文件名>#片段名?参数列表
另有URL方式进行连接并传输数据的方式,涉及到Tomcat服务器,在JavaWeb阶段再详细介绍。

举例实践——TCP

一、创建一个客户端与服务器端,并实现两者连接与发送数据
先运行服务器端,再运行客户端

public class TCPTest1 {
    @Test
    public void client(){

        Socket socket = null;
        OutputStream os = null;
        try {
            //创建InetAddress对象以供Socket使用
            InetAddress inet = InetAddress.getByName("127.0.0.1");

            //创建Socket对象,并指明要传输的端口号
            socket = new Socket(inet, 40000);

            //创建输出流以供输出
            os = socket.getOutputStream();

            os.write("你好,清河".getBytes());
        } catch (IOException 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();
                }
            }
        }
    }

    @Test
    public void server(){
        ServerSocket ss = null;
        Socket socket = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;
        try {
            //创建服务器端的Socket
            ss = new ServerSocket(40000);

            //创建接收用的socket
            socket = ss.accept();

            //创建输入流以接收文件
            is = socket.getInputStream();

            //使用字节流以实现数据的写入
            baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[5];
            int len;
            while((len = is.read(buffer)) != -1){
                baos.write(buffer, 0, len);
            }

            System.out.println(baos.toString());
            System.out.println("收到了来自于:" + socket.getInetAddress().getHostAddress() + "的消息");
        } 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 (ss != null) {
                try {
                    ss.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}
//终端输出:
你好,清河
收到了来自于:127.0.0.1的消息

二、从客户端发送文件给服务器端并保存

public class TCPTest2 {
    @Test
    public void client(){
        Socket socket = null;
        OutputStream os = null;
        FileInputStream fis = null;
        try {
            InetAddress inet = InetAddress.getByName("127.0.0.1");
            socket = new Socket(inet, 40000);
            os = socket.getOutputStream();

            fis = new FileInputStream(new File("xshell.png"));

            byte[] buffer = new byte[1024];
            int len;
            while((len = fis.read(buffer)) != -1){
                os.write(buffer, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            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() throws IOException {
        ServerSocket ss = null;
        Socket socket = null;
        InputStream is = null;
        FileOutputStream fos = null;
        try {
            ss = new ServerSocket(40000);
            socket = ss.accept();
            is = socket.getInputStream();

            fos = new FileOutputStream(new File("pic.png"));
            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 (fos != null) {
                fos.close();
            }
            if (is != null) {
                is.close();
            }
            if (socket != null) {
                socket.close();
            }
            if (ss != null) {
                ss.close();
            }
        }
    }
}

三、通过socket传输图片并向客户端返回数据

public class TCPTest3 {
    @Test
    public void client(){
        Socket socket = null;
        OutputStream os = null;
        FileInputStream fis = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;
        try {
            InetAddress inet = InetAddress.getByName("127.0.0.1");
            socket = new Socket(inet, 40000);
            os = socket.getOutputStream();

            fis = new FileInputStream(new File("xshell.png"));

            byte[] buffer = new byte[1024];
            int len;
            while((len = fis.read(buffer)) != -1){
                os.write(buffer, 0, len);
            }
            //.read()是一种阻塞的方法,需要进行手动的关闭。
            socket.shutdownOutput();

            is = socket.getInputStream();
            baos = new ByteArrayOutputStream();
            byte[] bufferr = new byte[20];
            int len1;
            while((len1 = is.read(bufferr)) != -1){
                baos.write(bufferr, 0, len1);
            }
            System.out.println(baos.toString());



        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            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(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 {
            ss = new ServerSocket(40000);
            socket = ss.accept();
            is = socket.getInputStream();

            fos = new FileOutputStream(new File("pic2.png"));
            byte[] buffer = new byte[1024];
            int len;
            while((len = is.read(buffer)) != -1){
                fos.write(buffer, 0, len);
            }

            os = socket.getOutputStream();
            os.write("你好,我收到了图片。".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.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();
                }
            }
            if(os != null){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
//客户端内容
你好,我收到了图片。

举例实践——UDP

使用UDP的方式发送一串字符串

public class UDPTest1 {
    @Test
    public void sender() throws IOException {
        //创建一个Socket用来发送
        DatagramSocket socket = new DatagramSocket();

        String str = "UDP导弹来啦";
        byte[] buffer = str.getBytes();
        InetAddress inet = InetAddress.getLocalHost();
        //创建一个Packet用来保存数据
        DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length, inet, 40001);

        socket.send(packet);
        socket.close();
    }

    @Test
    public void receiver() throws IOException {
        //创建一个Socket用来接收
        DatagramSocket socket = new DatagramSocket(40001);
        byte[] buffer = new byte[100];

        //创建一个Packet用来保存
        DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
        socket.receive(packet);

        System.out.println(new String(packet.getData(), 0, packet.getLength()));

        socket.close();
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值