Java高级编程基础——网络编程初理解

一、网络编程中的两个主要问题

  • 如何准确定位网络上的一台或多态主机:如何定位主机上的特定的应用
  • 找到主机后如何进行高高效可靠的数据传输

二、通信要素一——IP和端口号

IP:设备在网络中的地址,唯一标识
IP分为IPV4(32位)和IPV6(128位,冒分十六进制表示法)

端口号(0~65535):用于标识计算机上运行的进程(程序),区分应用程序

公认端口:
注册端口:
动态/私有端口:

IP+端口号 ===> Socket套接字

2.1、InetAddress类

2.1.1 InetAddress实例化

getByName(String host),getLocalHost()

        try {
       		//获取本机地址
            System.out.println(InetAddress.getLocalHost());
            InetAddress inet1 =  InetAddress.getByName("localhost");
            System.out.println(inet1);  
			//通过域名获取地址
            InetAddress inet2 =  InetAddress.getByName("www.baidu.com");
            System.out.println(inet2);  

            InetAddress inet3 =  InetAddress.getByName("196.168.10.14");
            System.out.println(inet3);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }

输出:

WRGHO-20210121P/192.168.31.160
localhost/127.0.0.1
www.baidu.com/14.215.177.39
/196.168.10.14

2.1.2 InetAddress的两个常用方法

getHostName():获取域名
getHostAddress:获取主机地址IP

            InetAddress inet2 =  InetAddress.getByName("www.baidu.com");
            System.out.println(inet2);//  www.baidu.com/14.215.177.38
            System.out.println(inet2.getHostName());
            System.out.println(inet2.getHostAddress());

输出:

www.baidu.com/14.215.177.38
www.baidu.com
14.215.177.38

三、通信要素二——网络协议

3.1 概念理解

  • 网络协议指的是计算机网络中互相通信的对等实体之间交换信息时所必须遵守的规则的集合。对传输代码,代码结构,传输控制步骤,出错控制等指定标准
  • 通信协议的分层思想:同层之间可通行、上一层可以调用下一层,中间有隔层的层之间不发生关系。各层之间互不影响

3.2传输层中的两个重要协议TCP/UDP

TCP协议UDP协议
使用TCP前,需先建立TCP连接,形成传输数据通道将数据、源、目的封装成数据包,不需要建立连接
传输前采用”三次握手“方式,点对点通信,是可靠的每个数据报的大小限制在64k内
TCP协议进行通信的两个应用进程:客户端、服务器端发送不管对方是否准备好,接收方也不确认,故是不可靠的
在连接中可进行大数据量的传输可以广播发送
传输完毕,释放已建立的连接藕、发送数据结束时无需释放资源,开销小,速度低

3.2.1 TCP 网络编程(Transmission Control Protocol)

三次握手

在这里插入图片描述

四次挥手

在这里插入图片描述
在这里插入图片描述模拟客户端代码:

    //模拟客户端
    public void client()  {
        Socket socket = null;
        OutputStream os = null;
        try {
            //1、创建socket对象,指明服务器端的ip和端口号
            InetAddress serverID = InetAddress.getByName("192.168.31.160");
            socket = new Socket(serverID,8899);

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

            //3、用输出流写出数据
            os.write("Hello,我是客户端!".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();
                }
            }
        }

    }

模拟服务器端代码:

    public void server() {

        ServerSocket serverSocket = null;
        Socket socket = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;
        try {
            //1、创建服务器端socket:ServerSocket指明自己的端口号
            serverSocket = new ServerSocket(8899);

            //2、调用accept接受来自客户端的socket
            socket = serverSocket.accept();

            //3、获取输入流
            is = socket.getInputStream();

            //4、读取输入流中的数据
            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());
            //查看发送端地址和ip
            System.out.println(socket.getInetAddress().getHostAddress());

        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            //5、关闭资源
            if (baos != null ) {
                try {
                    baos.close();
                    is.close();
                    socket.close();
                    serverSocket.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();
                }
            }
        }
    }
例题

题目:客户端发送文件给服务器端,服务器端保存到本地,服务器返回信息给客户端

客户端:

    public void client() {
        Socket socket = null;
        OutputStream outputStream = null;
        BufferedInputStream bis = null;
        ByteArrayOutputStream baos = null;

        try {
            //1、创建套接字,指明服务ip,和端口号
            InetAddress inetAddress = InetAddress.getByName("192.168.31.160");
            socket = new Socket(inetAddress, 8899);

            //2、获取输出流
            outputStream = socket.getOutputStream();

            //3、提供要发送的文件
            bis = new BufferedInputStream(new FileInputStream("皮卡丘.jpg"));

            //4、输出流发送文件
            int len;
            byte[] buffer = new byte[1024];
            while ((len = bis.read(buffer)) != -1){//read是一种阻塞的方法
                outputStream.write(buffer);
            }
            //关闭数据输出
            socket.shutdownOutput();

            //5、接收来自服务器端的数据,并显示到控制台上
            InputStream is = socket.getInputStream();
            baos = new ByteArrayOutputStream();
            byte[] buffer1 = new byte[20];
            int len1;
            while ((len1 = is.read(buffer1)) != -1){
                baos.write(buffer1,0,len1);
            }

            System.out.println(baos);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //6、关闭流
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                baos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

服务器端:

    public void server(){
        Socket socket = null;
        InputStream inputStream = null;
        BufferedOutputStream bos = null;
        OutputStream outputStream = null;
        try {
            //1、创建ServerSocket指明端口号
            ServerSocket serverSocket = new ServerSocket(8899);

            //2、调用accept接收socket
            socket = serverSocket.accept();

            //3、获取输入流
            inputStream = socket.getInputStream();


            //4、造输出流
            bos = new BufferedOutputStream(new FileOutputStream("皮卡丘TCP传输.jpg"));

            //5、获取socket中的数据
            int len;
            byte[] buffer = new byte[1024];
            while ((len = inputStream.read(buffer)) != -1){

                bos.write(buffer,0,len);
            }

            System.out.println("图片传输完成");

            //6、服务器端给予客户端反馈
            //6.1提供输出流
            outputStream = socket.getOutputStream();
            outputStream.write("文件发送成功!".getBytes());


        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //7、关闭流
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }


            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

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

            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

3.2.2 UDP 网络通信(User Datagram Protocol)

UDP模拟cs传输数据
sent:

    //发送端
    @Test
    public void send() throws IOException {

        DatagramSocket socket = new DatagramSocket();

        //封装数据包
        String str = "我是UDP数据报";
        byte [] data = str.getBytes();
        InetAddress address = InetAddress.getByName("192.168.31.160");
        DatagramPacket packet = new DatagramPacket(data,0,data.length,address,9090);//封装数据

        socket.send(packet);

        socket.close();

    }

reciver:

    //接收端
    @Test
    public void reciver() throws IOException {

        DatagramSocket socket = new DatagramSocket(9090);

        byte[] buffer = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);
        socket.receive(packet);

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

        socket.close();

    }

在这里插入图片描述

3.3 URL编程

  • 同一资源定位符,对应互联网的某一资源地址
  • URL的基本结构:<传输协议>://<主机名>:<端口号>/<文件名>#片段名?参数列表

URL类常用方法

功能方法
获取协议名getProtocol()
获取URL主机名getHost()
获取URL端口号getPort()
获取URL文件路径getPath()
获取URL文件名getFile()
获取URL查询名getQuery()

3.3.1 从Tomcat下载资源

步骤图解

在这里插入图片描述

代码
    public static void main(String[] args){

        HttpURLConnection urlConnection = null;
        InputStream is = null;
        FileOutputStream fos = null;
        try {
            URL url = new URL("http://127.0.0.1:8080/hello/cat.png");

            urlConnection = (HttpURLConnection)url.openConnection();

            //获取连接
            urlConnection.connect();

            //获取流
            is = urlConnection.getInputStream();
            fos = new FileOutputStream(new File("guigu20210914\\cat_downloadfromTomcat1.png"));

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

            System.out.println("下载完成!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {


            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (is != null) {
                try {
                    is.close();
                    urlConnection.disconnect();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值