java_网络编程

一、网络的相关概念

(一)网络通信

在这里插入图片描述

(二)网络

在这里插入图片描述

(三)ip地址

在这里插入图片描述
在这里插入图片描述

(四)ipv4地址分类

在这里插入图片描述

(五)域名

在这里插入图片描述

(六)端口号

在这里插入图片描述
在这里插入图片描述

(七)网络通信协议

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(八)网络通信协议

在这里插入图片描述

(九)TCP和UDP

在这里插入图片描述

在这里插入图片描述

二、InetAddress类

(一)相关方法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.hspedu.api;

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

public class API_ {
    public static void main(String[] args) throws UnknownHostException {

        //1.获取本机的InetAddress 对象
        InetAddress localHost = InetAddress.getLocalHost();
        System.out.println(localHost);//LAPTOP-J6E1LFVM/10.24.7.56

        //2.根据指定主机名 获取InetAddress 对象
        InetAddress host1 = InetAddress.getByName("LAPTOP-J6E1LFVM");
        System.out.println("host1=" + host1);//host1=LAPTOP-J6E1LFVM/10.24.7.56

        //3.根据域名返回InetAddress对象,比如www.baidu.com对象
        InetAddress host2 = InetAddress.getByName("www.baidu.com");
        System.out.println("host2=" + host2);//host2=www.baidu.com/183.232.231.174

        //4.通过InetAddress 对象,获取对应主机地址
        String hostAddress = host2.getHostAddress();
        System.out.println("host2 对象的ip = " + hostAddress);//host2 对象的ip = 183.232.231.174

        //5.通过InetAddress对象,获取对象的主机名/或者域名
        String hostName = host2.getHostName();
        System.out.println("host2对应的主机名/域名=" + hostName);//host2对应的主机名/域名=www.baidu.com
    }
}

三、Socket

(一)基本介绍

在这里插入图片描述
在这里插入图片描述

四、TCP网络通信编程

(一)基本介绍

在这里插入图片描述

(二)应用案例1(使用字节流)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
先运行服务端,再运行客户端

package com.hspedu.socket;



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

//服务端
public class SocketTCP1Server {
    public static void main(String[] args) throws IOException {

        //1.在本机的9999端口监听,等待连接
        //  要求在本机没有其他服务在监听9999
        //  这个ServerSocket 可以通过accept() 返回多个Socket【多个客户端连接服务端的并发】
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("服务端,在9999端口监听,等待连接");

        //2.当没有客户端连接9999端口时,程序会阻塞,等待连接
        //   如果有客户端连接,则会返回Socket对象,程序会继续
        Socket socket = serverSocket.accept();
        System.out.println("服务端 socket=" + socket.getClass());

        //3.通过socket.getInputStream() 读取客户端写入到数据通道的数据,显示
        InputStream inputStream = socket.getInputStream();
        //4.IO读取
        byte[] buf = new byte[1024];
        int readLen = 0;
        while((readLen = inputStream.read(buf)) != -1) {
            System.out.println(new String(buf, 0, readLen));//根据读取到的实际长度,显示内容
        }
        //5.关闭流和socket
        inputStream.close();
        socket.close();
        serverSocket.close();//关闭
    }
}

package com.hspedu.socket;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;

//客户端,发送”hello,server“给服务端
public class SocketTCP01Client {
    public static void main(String[] args) throws IOException {
        //1.连接服务端(ip,端口)
        //连接这台这台主机的9999端口,如果连接成功,返回socket对象
        Socket socket = new Socket(InetAddress.getLocalHost(),9999);
        System.out.println("客户端socket返回=" + socket.getClass());

        //2.连接上后,生成Socket,通过socket.getOutputStream
        //  得到和socket对象关联的输出流对象
        OutputStream outputStream = socket.getOutputStream();
        //3.通过输出流,写入数据到数据通道
        outputStream.write("hello,server".getBytes());
        //4.关闭流对象和socket,必须关闭
        outputStream.close();
        socket.close();
        System.out.println("客户端退出");
    }
}

(三)应用案例2(使用字节流)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.hspedu.socket;



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

//服务端
@SuppressWarnings({"all"})
public class SocketTCP2Server {
    public static void main(String[] args) throws IOException {

        //1.在本机的9999端口监听,等待连接
        //  要求在本机没有其他服务在监听9999
        //  这个ServerSocket 可以通过accept() 返回多个Socket【多个客户端连接服务端的并发】
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("服务端,在9999端口监听,等待连接");

        //2.当没有客户端连接9999端口时,程序会阻塞,等待连接
        //   如果有客户端连接,则会返回Socket对象,程序会继续
        Socket socket = serverSocket.accept();
        System.out.println("服务端 socket=" + socket.getClass());

        //3.通过socket.getInputStream() 读取客户端写入到数据通道的数据,显示
        InputStream inputStream = socket.getInputStream();
        //4.IO读取
        byte[] buf = new byte[1024];
        int readLen = 0;
        while((readLen = inputStream.read(buf)) != -1) {
            System.out.println(new String(buf, 0, readLen));//根据读取到的实际长度,显示内容
        }
        //5.获取socket相关联的输出流
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("hello,client".getBytes());
        //设置结束标准
        socket.shutdownOutput();
        //6.关闭流和socket
        outputStream.close();//关闭输出流
        inputStream.close();
        socket.close();
        serverSocket.close();//关闭
    }
}

package com.hspedu.socket;

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

//客户端,发送”hello,server“给服务端
@SuppressWarnings({"all"})
public class SocketTCP02Client {
    public static void main(String[] args) throws IOException {
        //1.连接服务端(ip,端口)
        //连接这台这台主机的9999端口,如果连接成功,返回socket对象
        Socket socket = new Socket(InetAddress.getLocalHost(),9999);
        System.out.println("客户端socket返回=" + socket.getClass());

        //2.连接上后,生成Socket,通过socket.getOutputStream
        //  得到和socket对象关联的输出流对象
        OutputStream outputStream = socket.getOutputStream();
        //3.通过输出流,写入数据到数据通道
        outputStream.write("hello,server".getBytes());
        //设置结束标准
        socket.shutdownOutput();
        //4.获取和socket关联的输入流,读取数据(字节),并显示
        InputStream inputStream = socket.getInputStream();
        byte[] buf = new byte[1024];
        int readLen = 0;
        while((readLen = inputStream.read(buf)) != -1) {
            System.out.println(new String(buf, 0, readLen));
        }
        //5.关闭流对象和socket,必须关闭
        inputStream.close();//关闭
        outputStream.close();
        socket.close();
        System.out.println("客户端退出");
    }
}

(四)应用案例3(使用字符流)

在这里插入图片描述
在这里插入图片描述

package com.hspedu.socket;



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

//服务端
@SuppressWarnings({"all"})
public class SocketTCP3Server {
    public static void main(String[] args) throws IOException {

        //1.在本机的9999端口监听,等待连接
        //  要求在本机没有其他服务在监听9999
        //  这个ServerSocket 可以通过accept() 返回多个Socket【多个客户端连接服务端的并发】
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("服务端,在9999端口监听,等待连接");

        //2.当没有客户端连接9999端口时,程序会阻塞,等待连接
        //   如果有客户端连接,则会返回Socket对象,程序会继续
        Socket socket = serverSocket.accept();
        System.out.println("服务端 socket=" + socket.getClass());

        //3.通过socket.getInputStream() 读取客户端写入到数据通道的数据,显示
        InputStream inputStream = socket.getInputStream();
        //4.IO读取 使用InputStreamReader 将inputStream 转换成字符流
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String s = bufferedReader.readLine();
        System.out.println(s);

        //5.获取socket相关联的输出流
        OutputStream outputStream = socket.getOutputStream();
        //使用字符输出流的方式回复信息
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
        bufferedWriter.write("hello client 字符流");
        bufferedWriter.newLine();//插入一个换行符,表示回复内容的结束
        bufferedWriter.flush();//注意需要手动的flush

        //6.关闭流和socket
        bufferedWriter.close();//关闭输出流
        bufferedReader.close();
        socket.close();
        serverSocket.close();//关闭
    }
}

package com.hspedu.socket;

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

//客户端,发送”hello,server“给服务端
@SuppressWarnings({"all"})
public class SocketTCP03Client {
    public static void main(String[] args) throws IOException {
        //1.连接服务端(ip,端口)
        //连接这台这台主机的9999端口,如果连接成功,返回socket对象
        Socket socket = new Socket(InetAddress.getLocalHost(),9999);
        System.out.println("客户端socket返回=" + socket.getClass());

        //2.连接上后,生成Socket,通过socket.getOutputStream
        //  得到和socket对象关联的输出流对象
        OutputStream outputStream = socket.getOutputStream();
        //3.通过输出流,写入数据到数据通道,使用字符流
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
        bufferedWriter.write("hello,server 字符流");
        bufferedWriter.newLine();//插入一个换行符,表示写入的内容结束,注意,要求对方使用readLine()
        bufferedWriter.flush();//如果使用字符流,需要手动刷新,否则数据不会写入通道


        //设置结束标准
        socket.shutdownOutput();
        //4.获取和socket关联的输入流,读取数据(字节),并显示
        InputStream inputStream = socket.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String s = bufferedReader.readLine();
        System.out.println(s);


        //5.关闭流对象和socket,必须关闭
        bufferedReader.close();//关闭外层流![在这里插入图片描述](https://img-blog.csdnimg.cn/b88dfbee30674b0293c554ab3c59c049.png)

        bufferedWriter.close();
        socket.close();
        System.out.println("客户端退出");
    }
}

(五)应用案例4

在这里插入图片描述

在这里插入图片描述

package com.hspedu.upload;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * 此类用于演示关于流的读写方法
 *
 */
public class StreamUtils {
	/**
	 * 功能:将输入流转换成byte[], 即可以把文件的内容读入到byte[]
	 * @param is
	 * @return
	 * @throws Exception
	 */
	public static byte[] streamToByteArray(InputStream is) throws Exception{
		ByteArrayOutputStream bos = new ByteArrayOutputStream();//创建输出流对象
		byte[] b = new byte[1024];//字节数组
		int len;
		while((len=is.read(b))!=-1){//循环读取
			bos.write(b, 0, len);//把读取到的数据,写入bos	
		}
		byte[] array = bos.toByteArray();//然后将bos 转成字节数组
		bos.close();
		return array;
	}
	/**
	 * 功能:将InputStream转换成String
	 * @param is
	 * @return
	 * @throws Exception
	 */
	
	public static String streamToString(InputStream is) throws Exception{
		BufferedReader reader = new BufferedReader(new InputStreamReader(is));
		StringBuilder builder= new StringBuilder();
		String line;
		while((line=reader.readLine())!=null){
			builder.append(line+"\r\n");
		}
		return builder.toString();
		
	}

}

package com.hspedu.upload;

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

//文件上传的服务端
public class TCPFileUploadServer {
    public static void main(String[] args) throws Exception {
        //1.服务端在本机监听8888端口
        ServerSocket serverSocket = new ServerSocket(8888);
        System.out.println("服务端在8888端口监听    ");
        //2.等待连接
        Socket socket = serverSocket.accept();

        //3.读取客户端发送的数据
        //  通过Socket得到输入流
        BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
        byte[] bytes = StreamUtils.streamToByteArray(bis);
        //4.将得到的bytes数组,写入到指定的路径,就得到一个文件了
        String descFilePath = "src\\qie2.png";
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(descFilePath));
        bos.write(bytes);
        bos.close();


        //向客户端回复收到图片
        //通过socket 获取到输出流(字符)
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        writer.write("收到图片");
        writer.flush();//把内容刷新到数据通道
        socket.shutdownOutput();//设置写入结束标记


        //关闭其他资源
        writer.close();
        bis.close();
        socket.close();
        serverSocket.close();
    }
}

package com.hspedu.upload;

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

//文件上传的客户端
public class TCPFileUploadClient {
    public static void main(String[] args) throws Exception {
        //创建客户端连接服务端8888,得到Socket对象
        Socket socket = new Socket(InetAddress.getLocalHost(), 8888);

        //创建读取磁盘文件的输入流
        String filePath = "d:\\aa.png";
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath));

        //bytes 就是filePath对应的文件数组
        byte[] bytes = StreamUtils.streamToByteArray(bis);

        //通过socket获取到输出流,将bytes数据发送给服务端
        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
        bos.write(bytes);//将文件对应的字节数组写入到数据通道

        bis.close();
        socket.shutdownOutput();//设置写入数据的结束标记

        //===接收从服务端回复的信息===
        InputStream inputStream = socket.getInputStream();
        //使用StreamUtils 的方法,直接将inputStream 读取到的内容转成String
        String s = StreamUtils.streamToString(inputStream);
        System.out.println(s);


        //关闭相关的流
        inputStream.close();
        bos.close();
        socket.close();

    }
}

(六)netstat 指令

在这里插入图片描述

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

在这里插入图片描述
在这里插入图片描述

五、UDP网络通信编程【了解】

(一)基本介绍

在这里插入图片描述

(二)基本流程

在这里插入图片描述
在这里插入图片描述

(三)应用案例

在这里插入图片描述
在这里插入图片描述

package com.hspedu.udp;

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

//UDP接收端
public class UDPReceiverA {
    public static void main(String[] args) throws IOException {
        //1.创建一个DatagramSocket 对象,准备在9999 接收数据
        DatagramSocket socket = new DatagramSocket(9999);

        //2.构建一个DatagramPacket对象,准备接收数据
        //数据包最大64k以内
        byte[] buf = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buf, buf.length);

        //3.调用接收方法,将通过网络传输的DatagramPacket对象
        //填充到packet对象
        //当有数据包发送到本机的9999端口时,就会接收到数据
        //如果没有数据包发送到本机的9999端口时,就会阻塞等待
        System.out.println("接收端A 等待接收数据...");
        socket.receive(packet);

        //4.可以把packet 进行拆包 取出数据,并显示
        int length = packet.getLength();//实际接收到的数据字节长度
        byte[] data = packet.getData();//接收到数据

        String s = new String(data, 0, length);
        System.out.println(s);

        //5.关闭资源
        socket.close();
        System.out.println("A端退出");
    }
}

package com.hspedu.udp;

import java.io.IOException;
import java.net.*;

//发送端B
public class UDPSenderB {
    public static void main(String[] args) throws IOException {

        //创建DatagramSocket对象,准备在9998端口 接收数据
        DatagramSocket socket = new DatagramSocket(9998);

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

        //封装的DatagramPacket对象,data 内容字节数组,data.length,主机IP,端口
        DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName("192.168.11.1"), 9999);

        socket.send(packet);

        //关闭资源
        socket.close();
        System.out.println("B端退出");
    }
}

package com.hspedu.udp;

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

//UDP接收端
public class UDPReceiverA {
    public static void main(String[] args) throws IOException {
        //1.创建一个DatagramSocket 对象,准备在9999 接收数据
        DatagramSocket socket = new DatagramSocket(9999);

        //2.构建一个DatagramPacket对象,准备接收数据
        //数据包最大64k以内
        byte[] buf = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buf, buf.length);

        //3.调用接收方法,将通过网络传输的DatagramPacket对象
        //填充到packet对象
        //当有数据包发送到本机的9999端口时,就会接收到数据
        //如果没有数据包发送到本机的9999端口时,就会阻塞等待
        System.out.println("接收端A 等待接收数据...");
        socket.receive(packet);

        //4.可以把packet 进行拆包 取出数据,并显示
        int length = packet.getLength();//实际接收到的数据字节长度
        byte[] data = packet.getData();//接收到数据

        String s = new String(data, 0, length);
        System.out.println(s);

        //======回复信息数据给B
        //将需要发送的数据,封装到DatagramPacket对象
        data = "好的,明天见".getBytes();

        //封装的DatagramPacket对象,data 内容字节数组,data.length,主机IP,端口
        packet = new DatagramPacket(data, data.length, InetAddress.getByName("192.168.11.1"), 9998);

        socket.send(packet);//发送



        //5.关闭资源
        socket.close();
        System.out.println("A端退出");
    }
}

package com.hspedu.udp;

import java.io.IOException;
import java.net.*;

//发送端B
@SuppressWarnings({"all"})
public class UDPSenderB {
    public static void main(String[] args) throws IOException {

        //创建DatagramSocket对象,准备在9998端口 接收数据
        DatagramSocket socket = new DatagramSocket(9998);

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

        //封装的DatagramPacket对象,data 内容字节数组,data.length,主机IP,端口
        DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName("192.168.11.1"), 9999);

        socket.send(packet);

        //3.====接收从A端回复的信息
        //(1)构建一个DatagramPacket对象,准备接收数据
        //数据包最大64k以内
        byte[] buf = new byte[1024];
        packet = new DatagramPacket(buf, buf.length);

        //(2)调用接收方法,将通过网络传输的DatagramPacket对象
        //填充到packet对象
        //当有数据包发送到本机的9998端口时,就会接收到数据
        //如果没有数据包发送到本机的9998端口时,就会阻塞等待
        socket.receive(packet);

        //(3)可以把packet 进行拆包 取出数据,并显示
        int length = packet.getLength();//实际接收到的数据字节长度
        data = packet.getData();//接收到数据

        String s = new String(data, 0, length);
        System.out.println(s);

        //关闭资源
        socket.close();
        System.out.println("B端退出");
    }
}

六、本章作业

(一)编程题

在这里插入图片描述

package com.hspedu.homework;



import com.hspedu.upload.StreamUtils;

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

//服务端
@SuppressWarnings({"all"})
public class Homework01Server {
    public static void main(String[] args) throws IOException {

        //1.在本机的9999端口监听,等待连接
        //  要求在本机没有其他服务在监听9999
        //  这个ServerSocket 可以通过accept() 返回多个Socket【多个客户端连接服务端的并发】
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("服务端,在9999端口监听,等待连接");

        //2.当没有客户端连接9999端口时,程序会阻塞,等待连接
        //   如果有客户端连接,则会返回Socket对象,程序会继续
        Socket socket = serverSocket.accept();



        //3.通过socket.getInputStream() 读取客户端写入到数据通道的数据,显示
        InputStream inputStream = socket.getInputStream();
        //4.IO读取 使用InputStreamReader 将inputStream 转换成字符流
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String s = bufferedReader.readLine();
        String answer = "";
        if("name".equals(s)) {
            answer = "我是john";
        } else if("hobby".equals(s)) {
            answer =  "编写java程序";
        } else {
            answer = "你说啥";
        }

        //5.获取socket相关联的输出流
        OutputStream outputStream = socket.getOutputStream();
        //使用字符输出流的方式回复信息
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
        bufferedWriter.write(answer);
        bufferedWriter.newLine();//插入一个换行符,表示回复内容的结束
        bufferedWriter.flush();//注意需要手动的flush

        //6.关闭流和socket
        bufferedWriter.close();//关闭输出流
        bufferedReader.close();
        socket.close();
        serverSocket.close();//关闭
    }
}

package com.hspedu.homework;

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

//客户端,发送”hello,server“给服务端
@SuppressWarnings({"all"})
public class Homework01Client {
    public static void main(String[] args) throws IOException {
        //1.连接服务端(ip,端口)
        //连接这台这台主机的9999端口,如果连接成功,返回socket对象
        Socket socket = new Socket(InetAddress.getLocalHost(),9999);

        //2.连接上后,生成Socket,通过socket.getOutputStream
        //  得到和socket对象关联的输出流对象
        OutputStream outputStream = socket.getOutputStream();
        //3.通过输出流,写入数据到数据通道,使用字符流
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));

        //从键盘读取用户问题
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入你的问题");
        String question = scanner.next();

        bufferedWriter.write(question);
        bufferedWriter.newLine();//插入一个换行符,表示写入的内容结束,注意,要求对方使用readLine()
        bufferedWriter.flush();//如果使用字符流,需要手动刷新,否则数据不会写入通道


        //设置结束标准
        socket.shutdownOutput();
        //4.获取和socket关联的输入流,读取数据(字节),并显示
        InputStream inputStream = socket.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String s = bufferedReader.readLine();
        System.out.println(s);


        //5.关闭流对象和socket,必须关闭
        bufferedReader.close();//关闭外层流
        bufferedWriter.close();
        socket.close();
        System.out.println("客户端退出");
    }
}

(二)编程题

在这里插入图片描述

package com.hspedu.homework;

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

//UDP接收端
@SuppressWarnings({"all"})
public class Homework02ReceiverA {
    public static void main(String[] args) throws IOException {
        //1.创建一个DatagramSocket 对象,准备在8888 接收数据
        DatagramSocket socket = new DatagramSocket(8888);

        //2.构建一个DatagramPacket对象,准备接收数据
        //数据包最大64k以内
        byte[] buf = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buf, buf.length);

        //3.调用接收方法,将通过网络传输的DatagramPacket对象
        //填充到packet对象
        System.out.println("接收端 等待接收问题");
        socket.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 = "what ?";
        }

        //======回复信息数据给B
        //将需要发送的数据,封装到DatagramPacket对象
        data = answer.getBytes();

        //封装的DatagramPacket对象,data 内容字节数组,data.length,主机IP,端口
        packet = new DatagramPacket(data, data.length, InetAddress.getByName("192.168.11.1"), 9998);

        socket.send(packet);//发送



        //5.关闭资源
        socket.close();
        System.out.println("A端退出");
    }
}

package com.hspedu.homework;

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

//发送端B
@SuppressWarnings({"all"})
public class Homework02SenderB {
    public static void main(String[] args) throws IOException {

        //创建DatagramSocket对象,准备在9998端口 接收数据
        DatagramSocket socket = new DatagramSocket(9998);

        //2.将需要发送的数据,封装到DatagramPacket对象
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入你的问题");
        String question = scanner.next();
        byte[] data = question.getBytes();

        //封装的DatagramPacket对象,data 内容字节数组,data.length,主机IP,端口
        DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName("192.168.11.1"), 8888);

        socket.send(packet);

        //3.====接收从A端回复的信息
        //(1)构建一个DatagramPacket对象,准备接收数据
        //数据包最大64k以内
        byte[] buf = new byte[1024];
        packet = new DatagramPacket(buf, buf.length);

        //(2)调用接收方法,将通过网络传输的DatagramPacket对象
        //填充到packet对象
        //当有数据包发送到本机的9998端口时,就会接收到数据
        //如果没有数据包发送到本机的9998端口时,就会阻塞等待
        socket.receive(packet);

        //(3)可以把packet 进行拆包 取出数据,并显示
        int length = packet.getLength();//实际接收到的数据字节长度
        data = packet.getData();//接收到数据

        String s = new String(data, 0, length);
        System.out.println(s);

        //关闭资源
        socket.close();
        System.out.println("B端退出");
    }
}

(三)编程题

在这里插入图片描述
在这里插入图片描述

package com.hspedu.homework;

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

//UDP接收端
@SuppressWarnings({"all"})
public class Homework02ReceiverA {
    public static void main(String[] args) throws IOException {
        //1.创建一个DatagramSocket 对象,准备在8888 接收数据
        DatagramSocket socket = new DatagramSocket(8888);

        //2.构建一个DatagramPacket对象,准备接收数据
        //数据包最大64k以内
        byte[] buf = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buf, buf.length);

        //3.调用接收方法,将通过网络传输的DatagramPacket对象
        //填充到packet对象
        System.out.println("接收端 等待接收问题");
        socket.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 = "what ?";
        }

        //======回复信息数据给B
        //将需要发送的数据,封装到DatagramPacket对象
        data = answer.getBytes();

        //封装的DatagramPacket对象,data 内容字节数组,data.length,主机IP,端口
        packet = new DatagramPacket(data, data.length, InetAddress.getByName("192.168.11.1"), 9998);

        socket.send(packet);//发送



        //5.关闭资源
        socket.close();
        System.out.println("A端退出");
    }
}

package com.hspedu.homework;


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

//先写文件下载的服务端
public class Homework03Server {
    public static void main(String[] args) throws Exception {
        //1.监听9999端口,
        ServerSocket serverSocket = new ServerSocket(9999);
        //2.等待客户端连接
        System.out.println("服务端在9999端口监听,等待下载文件");
        Socket socket = serverSocket.accept();
        //3.读取客户端要下载的文件名称
        InputStream inputStream = socket.getInputStream();
        //4.写入到字节数组
        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);

        //服务器上有两个文件,aa.png bb.png
        //如果客户下载的事bb.png 就放回该文件,否则一律返回aa.png

        String redFileName = "";
        if("bb.png".equals(downLoadFileName)) {
            redFileName = "src\\aa.png";
        } else {
            redFileName = "src\\bb.png";
        }

        //5.创建一个输入流,读取文件
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(redFileName));

        //6.使用工具类StreamUtils,读取文件到一个字节数组
        byte[] bytes = StreamUtils.streamToByteArray(bis);
        //7.得到Socket 关联的输出流
        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());

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

        //9.关闭相关资源
        bis.close();
        inputStream.close();
        socket.close();
        serverSocket.close();
        System.out.println("服务端退出");

    }
}

package com.hspedu.homework;

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

//文件下载的客户端
public class Homework03Client {
    public static void main(String[] args) throws Exception {

        //1.接收用户输入,指定下载文件名
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入要下载的文件名");
        String downloadFileName = scanner.next();

        //2.客户端连接服务端,准备发送
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);

        //3.获取和Socket关联的输出流
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write(downloadFileName.getBytes());
        //设置写入结束的标志
        socket.shutdownOutput();

        //4.读取服务端返回的文件(字节数据)
        BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
        byte[] bytes = StreamUtils.streamToByteArray(bis);

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

        //6.关闭相关的资源
        bos.close();
        bis.close();
        outputStream.close();
        socket.close();

        System.out.println("客户端下载完毕退出...");

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值