Java基础 - 网络编程 - netstat指令,UDP通信编程和网络编程总练习

netstat 指令

  1. netstat - an 可以查看当前主机网络情况,包括端口监听情况和网络连接情况
  2. netstat - an | more 可以分页显示,光标显示后点回车下一页
  3. ctrl + c 退出指令

请添加图片描述

请添加图片描述

案例表示

请添加图片描述

请添加图片描述

TCP网络通讯不为人知的秘密

  1. 当客户端连接到服务端后,实际上客户端也是通过一个端口和服务端进行通讯的,这个端口是TCP/IP来分配的

请添加图片描述

UDP网络通信编程[了解]

基本介绍

  1. 类DatagramSocket 和 DatagramPacket 实现了基于UDP协议网络程序。
  2. UDP数据报通过数据报套接字 DatagramSocket 发送和接收,系统不保证UDP数据报一定能够安全送到目的地,也不能确定什么时候可以抵达
  3. DatagramPacket 对象封装了UDP数据报,在数据中包含了发送端的IP地址和端口号以及接收端的IP地址和端口号
  4. UDP协议中每个数据报都给出了完整的地址信息,因此无需建立发送方和接收方的连接

基本流程

  1. 核心的两个类/对象 DatagramSocket与DatagramPacket
  2. 建立发送端,接收端(没有服务端和客户端概念)
  3. 发送数据前,建立数据包/报 (DatagramPack对象)
  4. 调用DatagramSocket的发送,接收方法
  5. 关闭DatagramSocket

请添加图片描述

请添加图片描述

应用案例

  1. 编写一个接收端A,和一个发送端B
  2. 接收端A在9999端口等待接受数据(receive)
  3. 发送端B向接收端A 发送数据“hello,明天吃火锅~”
  4. 接收端A接收到 发送端B发送的数据,回复“好的,明天见”,再退出
  5. 发送端接收 回复的数据,再退出

接收端

package com.tao.udp;

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

/**
 * Create By 刘鸿涛
 * 2022/2/8 9:55
 * UDP接收端
 */
public class UDPReceiverA {
    public static void main(String[] args) throws IOException {
        //1.创建一个 DatagramSocket 对象 准备在9999接收数据
        DatagramSocket datagramSocket = new DatagramSocket(9999);

        //2.构建一个DatagramPacket对象,准备接收数据
        //    在前面学习UDP协议时,知道一个UDP数据包最大64k
        byte[] buf = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buf, buf.length);

        //3.调用接收方法receive(),将通过网络传输的 DatagramPacket对象
        //提示:当有数据包发送到 本机的9999端口时,就会阻塞等待
        System.out.println("接收端A,9999端口, 等待接收数据....");
        datagramSocket.receive(packet);
        System.out.println("1");
        //4.可以把packet 进行拆包,取出数据,并显示
        int length = packet.getLength();    //实际接收到的数据字节长度
        byte[] data = packet.getData(); //接收到数据
        String s = new String(data, 0, length);
        System.out.println(s);

        data = "好的,明天见".getBytes();

        //说明:封装的 DatagramPacket 对象 data 内容字节数组,data.length,主机(IP),端口
//        InetAddress.getLocalHost()        //获得主机ip
        DatagramPacket datagramPacket = new DatagramPacket(data, data.length,
                InetAddress.getLocalHost(), 9998);//这里的127.0.0.1指发送给本机

        datagramSocket.send(datagramPacket);

        //关闭流
        datagramSocket.close();
        System.out.println("===接收端已终止===");
    }
}

发送端

package com.tao.udp;

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

/**
 * Create By 刘鸿涛
 * 2022/2/8 9:57
 * 发送端B ====> 也可以接收数据
 */
public class UDPSenderB {
    public static void main(String[] args)throws Exception {
        //创建 DatagramSocket对象,准备接收数据
        //
        //因为是在本机举例接收端和发送端,所以这个端口号最好不要相同,因为会分不清谁是接收方,
        // 谁是发送方,导致程序错乱,当然,如果是两台主机,那么就可以使用相同端口号,就比如
        // 是两个楼层中两个相同id的门一样,虽然id相同,但并不是一个门
        DatagramSocket datagramSocket = new DatagramSocket(9998);

        //2.将需要发送的数据,封装到 DatagramPacket对象
        byte[] data = "hello 明天吃火锅".getBytes();

        //说明:封装的 DatagramPacket 对象 data 内容字节数组,data.length,主机(IP),端口
//        InetAddress.getLocalHost()        //获得主机ip
        DatagramPacket datagramPacket = new DatagramPacket(data, data.length,
                InetAddress.getLocalHost(), 9999);//这里的127.0.0.1指发送给本机

        datagramSocket.send(datagramPacket);

        byte[] buf = new byte[1024];
        datagramPacket = new DatagramPacket(buf, buf.length);
        datagramSocket.receive(datagramPacket);
        int length = datagramPacket.getLength();    //实际接收到的数据字节长度
        byte[] data2 = datagramPacket.getData(); //接收到数据
        String s = new String(data2, 0, length);
        System.out.println(s);
        //关闭资源
        datagramSocket.close();
        System.out.println("===发送端已终止===");
    }
}

网络编程练习(课堂作业巩固)

TCP交互传输字节流回复

  1. 使用字节流的方式,编写一个客户端程序和服务端程序
  2. 客户端发送“name”,服务器端接收到后,返回,“我是nova”,nova是你自己的名字
  3. 客户端发送“hobby”,服务器端接收到后,返回“编写java程序”
  4. 不是这样两个问题,回复“你说啥呢”
package com.tao.homework.homework01;

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

/**
 * Create By 刘鸿涛
 * 2022/2/8 20:44
 */
public class Server {
    public static void main(String[] args) throws IOException {
        while(true) {
            ServerSocket serverSocket = new ServerSocket(5000);

            //监听
            System.out.println("等待客户端连接连接");
            Socket socket = serverSocket.accept();
            System.out.println("正在接收数据...");
            InputStream inputStream = socket.getInputStream();  //接收数据通道的数据

            //IO读取
            byte[] buf = new byte[1024];
            int len = 0;
            String s = "";
            while ((len = inputStream.read(buf)) != -1) {
                s = new String(buf, 0, len);
                if (s.equals("name")) {
                    s = "我是涛涛";
                } else if (s.equals("hobby")) {
                    s = "编写java程序";
                } else {
                    s = "你说啥";
                }
            }

            OutputStream outputStream = socket.getOutputStream();
            outputStream.write(s.getBytes());       //写入s到数据通道
            socket.shutdownOutput();                //结束语句,我说完了
            System.out.println("正在传输数据到数据通道...");
            //关闭流
            socket.close();
            inputStream.close();
            serverSocket.close();
            System.out.println("服务器端结束");
        }
    }
}

package com.tao.homework.homework01;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;

/**
 * Create By 刘鸿涛
 * 2022/2/8 20:48
 */
public class Client {
    public static void main(String[] args) throws IOException, InterruptedException {
        while(true) {
            Socket socket = new Socket(InetAddress.getLocalHost(), 5000);

            System.out.println("请输入问题");
            Scanner sc = new Scanner(System.in);
            String s = sc.next();

            OutputStream outputStream = socket.getOutputStream();
            outputStream.write(s.getBytes());
            socket.shutdownOutput();        //结束语句,证明我说完了

            InputStream inputStream = socket.getInputStream();
            byte[] buf = new byte[1024];
            int len = 0;
            while ((len = inputStream.read(buf)) != -1) {
                System.out.println(new String(buf, 0, len));
            }

            //关闭流
            socket.close();
            outputStream.close();

            System.out.println("客户端结束");
        }
    }
}

UDP交互传输字节流回复

  1. 编写一个接收端A,和一个发送端B,使用UDP协议完成
  2. 接收端在8888端口等待接收数据(receive)
  3. 发送端向接收端发送数据“四大名著是哪些”
  4. 接收端接收到发送端发送的问题后,返回“四大名著是<<红楼梦>>…",否则返回what?
  5. 接收端和发送端程序退出
package com.tao.homework.homework02;

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

/**
 * Create By 刘鸿涛
 * 2022/2/8 9:55
 * UDP接收端
 */
public class Homework02ReceiverA {
    public static void main(String[] args) throws IOException {
        //1.创建一个 DatagramSocket 对象 准备在9999接收数据
        DatagramSocket datagramSocket = new DatagramSocket(9999);

        //2.构建一个DatagramPacket对象,准备接收数据
        //    在前面学习UDP协议时,知道一个UDP数据包最大64k
        byte[] buf = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buf, buf.length);

        //3.调用接收方法receive(),将通过网络传输的 DatagramPacket对象
        //提示:当有数据包发送到 本机的9999端口时,就会阻塞等待
        System.out.println("接收端A,9999端口, 等待接收数据....");
        datagramSocket.receive(packet);
        //4.可以把packet 进行拆包,取出数据,并显示
        int length = packet.getLength();    //实际接收到的数据字节长度
        byte[] data = packet.getData(); //接收到数据
        String s = new String(data, 0, length);
        String answer = "";
        if ("四大名著有哪些".equals(s) ){
            answer = "四大名著 《红楼梦》《三国演义》《西游记》《水浒传》";
        }else {
            answer = "你说啥?";
        }
//        System.out.println(s);

        data = answer.getBytes();

        //说明:封装的 DatagramPacket 对象 data 内容字节数组,data.length,主机(IP),端口
//        InetAddress.getLocalHost()        //获得主机ip
        DatagramPacket datagramPacket = new DatagramPacket(data, data.length,
                InetAddress.getLocalHost(), 9998);//这里的127.0.0.1指发送给本机

        datagramSocket.send(datagramPacket);

        //关闭流
        datagramSocket.close();
        System.out.println("===接收端已终止===");
    }
}

package com.tao.homework.homework02;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;

/**
 * Create By 刘鸿涛
 * 2022/2/8 9:57
 * 发送端B ====> 也可以接收数据
 */
public class Homework02SenderB {
    public static void main(String[] args)throws Exception {
        //创建 DatagramSocket对象,准备接收数据
        //
        //因为是在本机举例接收端和发送端,所以这个端口号最好不要相同,因为会分不清谁是接收方,
        // 谁是发送方,导致程序错乱,当然,如果是两台主机,那么就可以使用相同端口号,就比如
        // 是两个楼层中两个相同id的门一样,虽然id相同,但并不是一个门
        DatagramSocket datagramSocket = new DatagramSocket(9998);

        //2.将需要发送的数据,封装到 DatagramPacket对象

        //把字符a包装送到数据通道
        System.out.println("请输入查询内容...");
        Scanner scanner = new Scanner(System.in);
        String a = scanner.next();
        byte[] data = a.getBytes();

        //说明:封装的 DatagramPacket 对象 data 内容字节数组,data.length,主机(IP),端口
//        InetAddress.getLocalHost()        //获得主机ip
        DatagramPacket datagramPacket = new DatagramPacket(data, data.length,
                InetAddress.getLocalHost(), 9999);//这里的127.0.0.1指发送给本机

        datagramSocket.send(datagramPacket);

        //接收数据通道传来内容
        byte[] buf = new byte[1024];
        datagramPacket = new DatagramPacket(buf, buf.length);
        datagramSocket.receive(datagramPacket);
        int length = datagramPacket.getLength();    //实际接收到的数据字节长度
        byte[] data2 = datagramPacket.getData(); //接收到数据
        String s = new String(data2, 0, length);
        System.out.println(s);
        //关闭资源
        datagramSocket.close();
        System.out.println("===发送端已终止===");
    }
}

TCP交互传输音乐文件

  1. 编写客户端程序和服务器端程序
  2. 客户端可以输入一个音乐文件名,比如高山流水,服务端收到音乐名后,可以给客户端返回这个音乐文件,如果服务器没有这个文件,返回一个默认的音乐即可.
  3. 客户端收到文件后,保存到本地d:\
  4. 该程序可以使用 StreamUtils.java

请添加图片描述

package com.tao.homework.homework03;

import com.tao.upload.StreamUtils;

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

/**
 * Create By 刘鸿涛
 * 2022/2/9 12:21
 */
public class Homework03Client {
    public static void main(String[] args) throws Exception {
        //找到服务器端口
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);

        OutputStream outputStream = socket.getOutputStream();
        System.out.println("请输入需要下载的音乐...");
        Scanner scanner = new Scanner(System.in);
        String downLoadFileName = scanner.next();
        outputStream.write(downLoadFileName.getBytes());
        socket.shutdownOutput();

        //接受数据
        BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
        byte[] bytes = StreamUtils.streamtoByteArray(bis);

        //得到一个输出流,准备将bytes写入到磁盘文件
        String filePath = "d:\\" + downLoadFileName + ".mp3";
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath));
        bos.write(bytes);



        //关闭流
        outputStream.close();
        socket.close();
        scanner.close();
        bis.close();
        bos.close();
        System.out.println("客户端关闭");

    }
}

package com.tao.homework.homework03;

import com.tao.homework.homework01.Server;
import com.tao.upload.StreamUtils;

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

/**
 * Create By 刘鸿涛
 * 2022/2/9 12:20
 */
public class Homework03Server {
    public static void main(String[] args) throws Exception {

        //1.监听 9999端口,等待客户端连接,并发送下载文件的名字
        ServerSocket serverSocket = new ServerSocket(9999);
        //2.等待客户端连接
        Socket socket = serverSocket.accept();
        //3.读取 客户端发送要下载的文件名
        //这里老师使用了while读取文件名,是考虑将来客户端发送的数据较大的情况
        InputStream inputStream = socket.getInputStream();
        byte[] b = new byte[1024];
        int len = 0;
        String downLoadFileName = "";
        while ((len = inputStream.read(b)) != -1){
            downLoadFileName = new String (b,0,len);
        }
        System.out.println("客户端希望下载文件名" + downLoadFileName);

        //src下有两个文件,一个是“青山”,一个“高山流水.MP3”
        //如果客户下载的是 “高山流水” 我们就返回该文件,否则默认返回“青山”
        String resFileName = "";
        //4.创建一个输入流,读取文件
        if ("高山流水".equals(downLoadFileName)){
            resFileName = "src\\高山流水.mp3";
        } else {
            resFileName = "src\\青山.mp3";
        }
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(resFileName));

        //5.实用工具类StreamUtils,读取文件到一个字节数组
        byte[] bytes = StreamUtils.streamtoByteArray(bis);

        //6.得到Socket关联的输出流
        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());

        //7.写入到数据通道,返回给客户端
        bos.write(bytes);
        socket.shutdownOutput();

        //8.关闭流
        serverSocket.close();
        socket.close();
        inputStream.close();
        bis.close();
        bos.close();
        System.out.println("服务端退出");

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

鬼鬼骑士

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

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

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

打赏作者

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

抵扣说明:

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

余额充值