0
点赞
收藏
分享

微信扫一扫

Java笔记22-Java高级编程部分-第十四章-网络编程

丹柯yx 2022-05-01 阅读 80

目录

14.1 网络编程的概述



在这里插入图片描述

package com.pfl.java1;

import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 *
 * 一、网络编程中有两个主要的问题:
 *  1.如何准确的定位网络上的一台或多台主机;定位主机上的特定应用
 *  2.找到主机后如何可靠高效的进行数据传输
 *
 * 二、网络编程中的两个要素:
 *  1.对应问题一:IP 和 端口号
 *  2.对应问题二:提供网络通信协议:TCP/IP参考模型(应用层、传输层、网络层、数据链路层、物理层)
 *
 * 三、通信要素一:IP和端口号
 *
 *  1. IP:唯一的标识Internet上的计算机(通信实体)
 *  2. 在Java中使用InetAddress类代表IP地址
 *  3. IP的分类 IPv4 和 IPv6;万维网 和 局域网
 *  4. 域名: www.baidu.com   www.mi.com   www.sina.com
 *  5. 本地回路地址:127.0.0.1 对应着:localhost
 *  6. 如何实例化InetAddress:两个方法:getByName(String host) 和 getLocalHost()
 *              两个常用方法:getHostName()  /  getHostAddress()
 *
 *  7. 端口号:正在计算机上运行的进程。
 *      要求:不同的进程有不同的端口号
 *      范围:被规定为一个16位的整数 0~65535。
 *
 *  8. 端口号与IP地址的组合得出一个网络套接字:Socket
 *  网络通信也可以叫做Socket通信,Socket编程
 *
 * @author pflik-
 * @create 2022-02-08 13:00
 */
public class InetAddressTest {

    public static void main(String[] args) {

        try {
            InetAddress inet1 = InetAddress.getByName("192.168.10.14");
            //inet1 就是对应着一个IP地址:"192.168.10.14"
            System.out.println(inet1);

            InetAddress inet2 = InetAddress.getByName("www.atguigu.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()
            System.out.println(inet2.getHostName());
            //getHostAddress()
            System.out.println(inet2.getHostAddress());


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


    }
}

14.2 网络通信要素概述

在这里插入图片描述

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


在这里插入图片描述


14.4 通信要素2:网络协议





建立链接的时候–三次握手:

14.5 TCP网络编程


例题

例题一:客户端发送内容给服务端,服务端将内容打印到控制台上。

package com.pfl.java1;

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;

/**
 * 实现TCP的网络编程
 * 例子1:客户端发送一段信息给服务端,服务端将数据显示在控制台上
 *
 *
 *
 * 快捷键:
 * Alt+Enter:提示处理报错情况
 * ctrl+Alt+T:处理异常try-catch-finally
 * ctrl+shift+上/下键:将选择的代码上下移动
 *
 * @author pflik-
 * @create 2022-02-08 18:56
 */
public class TCPTest1 {

    //注意:要先要启动服务端,在启动客户端
    //需求一:客户端给服务端发一句话
    //需求二:想看一下是谁发给服务端的

    //测试单元-客户端
    @Test
    public void client() {
        //发送数据
        Socket socket = null;
        OutputStream os = null;

        try {
            //1.创建Socket对象,指明服务器端的IP和端口号
            //获取对方(服务器端)的IP
            InetAddress inet = InetAddress.getByName("127.0.0.1");
            //创建一个Socket,里面包含(对方)具体的IP和端口号
            socket = new Socket(inet,8899);
            //2.获取一个输出流,用于输出数据
            //传输数据-发送
            os = socket.getOutputStream();
            //3.写出数据的操作
            os.write("你好,我是客户端mm".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4.资源的关闭
            //socket也是资源,类似与一个流一样,也需要关闭
            if(os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
        //有了close
        // 1.就需要上面的异常使用try-catch-finally
        // 2.在finally中关闭流和socket
        // 3.并且针对每个close()都要try...catch一下即可

    }

    //测试单元-服务端
    @Test
    public void server() {
        //接受数据/操作数据
        ServerSocket ss = null;
        Socket socket = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;

        try {
            //1.创建服务器端的Socket:ServerSocket,指明自己的端口号
            //同样对应是socket,在服务器中使用的ServerSocket--有异常就先throws一下
            ss = new ServerSocket(8899);
            //2.调用accept()表示接受来自于客户端的socket
            //用来接受来自客户端的Socket
            socket = ss.accept();
            //3.获取输入流
            //读入流
            is = socket.getInputStream();
            //想要把流动的数据显示到控制台上
            // 1.用read读出来
            // 2.不过发送的数据比较长,使用循环,并且需要长的byte数组

            //思路一:
            //不建议这样写,可能会有乱码
            //注:因为在客户端输入的是汉字,我们使用的是字节流(根据UTF-8,一个汉字占3个字节)
            //可以把byte数组大一些(汉字可以更多,不能确定有多少个字节)
            // 不过如果byte数组很小的话,在还原成String的时候就会出问题
            //所以这样是不可以的。
//        byte[] buffer = new byte[20];
//        int len;
//        while((len = is.read(buffer)) != -1) {
//            //发送的是文本,这时候需要转成String
//            String str = new String(buffer, 0, len);
//            System.out.print(str);
//        }

            //思路二:
            //引入新的知识--ByteArrayoutputStream
            //4.读取输入流中的数据
            baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[5];
            int len;
            while((len = is.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
                //那么这个数据写到哪里了呐?
                //baos也没有像原先的流一样指定文件
                //其实ByteArrayOutputStream有一个数组,往里面写就可以,不够会自己扩充
                //byte数组的大小是5,那么就是每次往baos里面写进去,先拼接好
                // 直到最后输入完成,开一个大的数组把全部内容(好多个大小为5的byte)还原为字符串
            }
            //这样就不会出现乱码的问题
            System.out.println(baos.toString());
            //这样就把数据输出到控制台上了
            //服务端接受的是客户端的socket,所以可以通过soket来获取客户端的信息
            //socket.getInetAddress():获取IP
            //socket.getInetAddress().getHostAddress():看一下IP的地址
            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();//服务器不想接受了,才把ServerSocket关掉
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        //注:
        // 涉及到资源的关闭,保证他一定能够执行,所以不能使用throws
        //需要把close之前的都要包起来
        //把资源关闭命令都放到finally中,并且把每个命令之前都要判断一下是否为'null'
        //在if判断后,把每个关闭命令都要try...catch一下
    }

}

在这里插入图片描述

例题二:客户端发送文件给服务端,服务端将文件保存在本地。

代码一–简化版:

package com.pfl.java1;

import org.junit.Test;

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

/**
 * 实现TCP的网络编程
 * 例题2.客户端发送文件给服务端,服务端将文件保存在本地。
 *
 * @author pflik-
 * @create 2022-04-27 20:59
 */
public class TCPTest2 {

    //注意:因为涉及到资源的关闭,不能使用throws解决问题
    //为了熟悉流程,只写成这样,可以参考例子一:里面有详细的内容
    @Test
    public void client() throws IOException {
        //1.创建Socket
        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9090);
        //2.获取一个输出流
        //socket需要往外传数据
        OutputStream os = socket.getOutputStream();
        //输出的数据是从客户端本地发出的文件
        //需要把文件读进来--为了效率,可以用缓冲流包一下
        //3.获取一个输入流
        FileInputStream fis = new FileInputStream(new File("Basketball-Kobe.jpg"));
        //接下来就是具体的读、写的过程了
        //4.读写过程
        byte[] buffer = new byte[1024];
        int len;
        //read到buffer中,返回值不等于-1
        while( (len = fis.read(buffer))!= -1) {
            os.write(buffer, 0, len);
        }

        //5.资源的关闭
        fis.close();
        os.close();
        socket.close();
    }

    @Test
    public void server() throws IOException {
        //1.造一个ServerSoket-指明自己的端口号
        ServerSocket ss = new ServerSocket(9090);
        //2.获取客户端的socket
        Socket socket = ss.accept();
        //3.获取客户端的一个输入流
        //获取一个读入-输入流
        InputStream is = socket.getInputStream();
        //4.保存数据到本地,建一个本地的操作
        FileOutputStream fos = new FileOutputStream(new File("Basketball-LeBron.jpg"));

        //5.读写的过程
        byte[] buffer = new byte[1024];
        int len;
        while((len = is.read(buffer)) != -1) {
            fos.write(buffer, 0, len);
            //此时这个文件就写出去了,写到fos里面去了
        }

        //6.资源的关闭
        fos.close();
        is.close();
        socket.close();
        ss.close();

    }
}

代码二-完整版:

package com.pfl.java1;

import org.junit.Test;

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

/**
 * 实现TCP的网络编程
 * 例题2.客户端发送文件给服务端,服务端将文件保存在本地。
 *
 * @author pflik-
 * @create 2022-04-27 20:59
 */
public class TCPTest2 {

    //注意:这里涉及到的异常,应该使用try-catch-finally处理
    // 因为涉及到资源的关闭,不能使用throws解决问题
    //为了熟悉流程,只写成这样,可以参考例子一:里面有详细的内容
    @Test
    public void client() {
        Socket socket = null;
        OutputStream os = null;
        FileInputStream fis = null;
        try {
            //1.创建Socket
            socket = new Socket(InetAddress.getByName("127.0.0.1"), 9090);
            //2.获取一个输出流
            //socket需要往外传数据
            os = socket.getOutputStream();
            //输出的数据是从客户端本地发出的文件
            //需要把文件读进来--为了效率,可以用缓冲流包一下
            //3.获取一个输入流
            fis = new FileInputStream(new File("Basketball-Kobe.jpg"));
            //接下来就是具体的读、写的过程了
            //4.读写过程
            byte[] buffer = new byte[1024];
            int len;
            //read到buffer中,返回值不等于-1
            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.造一个ServerSoket-指明自己的端口号
            ss = new ServerSocket(9090);
            //2.获取客户端的socket
            socket = ss.accept();
            //3.获取客户端的一个输入流
            //获取一个读入-输入流
            is = socket.getInputStream();
            //4.保存数据到本地,建一个本地的操作
            fos = new FileOutputStream(new File("Basketball-LeBron.jpg"));

            //5.读写的过程
            byte[] buffer = new byte[1024];
            int len;
            while((len = is.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
                //此时这个文件就写出去了,写到fos里面去了
            }
            System.out.println("接受成功!!!");
        } 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(socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(ss != null) {
                try {
                    ss.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

P626

举报

相关推荐

0 条评论