[Java]Java 网络编程(Socket)和反射

Posted Spring-_-Bear

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Java]Java 网络编程(Socket)和反射相关的知识,希望对你有一定的参考价值。

一、网络编程

1. IP

  1. IP 地址概念:用于唯一标识网络中的每台计算机(主机)
  2. DOS 查看 IP 地址:ipconfig
  3. IPV4 用 4 字节共 32 位标识一个 IP 地址(点分十进制)
  4. IPV6 用 8 字节共 128 位标识一个 IP 地址
  5. IP 地址的组成:网络地址 + 主机地址
  6. 127.0.0.1 表示本机地址
  7. 127.0.0.1 表示本机地址
分类表示方法范围
A0 + 7 位网络号 + 24 位主机号0.0.0.0 ~ 127.255.255.255
B10 + 14 位网络号 + 16 位主机号128.0.0.0 ~ 191.255.255.255
C110 + 21 位网络号 + 8 位主机号192.0.0.0 ~ 223.255.255.255
D1110 + 28 位多播组号224.0.0.0 ~ 239.255.255.255
E11110 + 27 位留待后用240.0.0.0 ~ 247.255.255.255

2. 域名、端口及网络协议

  1. 域名:将 IP 地址映射成域名(http 协议)
  2. 端口:用于标识计算机上特定的网络程序,以整数形式表示,范围是 0 ~ 65535,其中 0 ~ 1024 已被占用。常见的网络程序端口:ssh 22、ftp 21、smtp 25、http 80、tomcat 8080、mysql 3306、oracle 1521、sql server 1433
  3. TCP / IP(Transmission Control Protocol / Internet Protocol):传输控制协议 / 因特网互联协议,又名网络通讯协议

TCP/IP模型对应协议
应用层http、ftp、telnet、DNS···
传输层TCP、UDP···
网络层IP、ICMP、ARP···
物理 + 数据链路层Link

3. TCP、UDP 及 Socket

  1. TCP(Transmission Control Protocol):在使用 TCP 协议前,须先建立 TCP 连接,形成传输数据通道;传输前,采用 ”三次握手“ 方式建立连接,传输可靠;TCP 协议进行通信的两个应用程序:客户端、服务端;在连接中可进行大量数据的传输;传输完毕,需释放已建立的连接,效率较低
  2. UDP(User Data Protocol):将数据、源、目的封装成数据包,不需要建立连接,传输不可靠,无需释放资源,速度快;每个数据包的大小限制在 64K 以内
  3. Socket(套接字)开发网络应用程序时被广泛使用,以至于成为事实上的标准;通信的两端都要有 Socket,是两台机器间通信的端点;网络通信其实就是 Socket 间的通信;Socket 允许程序把网络连接当作是一个流,数据在两个 Socket 间通过 IO 传输;一般发起通信的应用程序属客户端,等待通信请求的为服务端

4. InetAddress 类

方法名功能
getLocalHost获取本机 InetAddress 对象
getByName根据指定主机名 / 域名获取 InetAddress 对象
getHostName获取 InetAddress 对象的主机名
getHostAddress获取 InetAddress 对象的 ip 地址
// 获取本机的 InetAddress 对象
InetAddress localHost = InetAddress.getLocalHost();
System.out.println(localHost);

// 根据指定主机名/域名获取 InetAddress 对象
InetAddress csdn = InetAddress.getByName("www.csdn.net");
System.out.println(csdn);
InetAddress springBear = InetAddress.getByName("SpringBear");
System.out.println(springBear);

// 获取 InetAddress 对象的主机名
System.out.println(localHost.getHostName());
System.out.println(csdn.getHostName());
// 获取 InetAddress 对象的 ip 地址
System.out.println(springBear.getHostAddress());
System.out.println(csdn.getHostAddress());

5. TCP 字节流编程

Server

// 监听端口
ServerSocket serverSocket = new ServerSocket(5555);
// 等待连接
Socket socket = serverSocket.accept();

// 从数据通道读取数据
InputStream inputStream = socket.getInputStream();
byte[] buf = new byte[1024];
int readLen;
while ((readLen = inputStream.read(buf)) != -1) 
   System.out.println(new String(buf, 0, readLen));

// 关闭 socket 的输入流
socket.shutdownInput();

// 写数据到数据通道
OutputStream outputStream = socket.getOutputStream();
outputStream.write("Hello,Client!".getBytes(StandardCharsets.UTF_8));

// 关闭资源
outputStream.close();
inputStream.close();
socket.close();
serverSocket.close();

Client

// 建立连接
Socket socket = new Socket(InetAddress.getLocalHost(), 5555);

// 写数据到数据通道
OutputStream outputStream = socket.getOutputStream();
outputStream.write("Hello,Server!".getBytes(StandardCharsets.UTF_8));
// 关闭 socket 的输出流
socket.shutdownOutput();

// 从数据通道读取数据
InputStream inputStream = socket.getInputStream();
byte[] buf = new byte[1024];
int readLen;
while ((readLen = inputStream.read(buf)) != -1) 
   System.out.println(new String(buf, 0, readLen));


// 关闭资源
inputStream.close();
outputStream.close();
socket.close();

6. TCP 字符流编程

Server

// 监听端口
ServerSocket serverSocket = new ServerSocket(6666);
// 等待连接
Socket socket = serverSocket.accept();

// 从数据通道读取信息
InputStream inputStream = socket.getInputStream();
// 字节输入流转换成字符输入流
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
System.out.println(bufferedReader.readLine());

// 写数据到数据通道
OutputStream outputStream = socket.getOutputStream();
// 字节输出流转换成字符输出流
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
bufferedWriter.write("Hello,Client!");
// 行分隔符,写入结束标志
bufferedWriter.newLine();
// 刷新缓冲区,写入数据通道
bufferedWriter.flush();

// 关闭资源
bufferedWriter.close();
bufferedReader.close();
socket.close();
serverSocket.close();

Client

// 建立连接
Socket socket = new Socket(InetAddress.getLocalHost(), 6666);

// 写入数据到数据通道
OutputStream outputStream = socket.getOutputStream();
// 字符输出流转换从字节输出流
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
bufferedWriter.write("Hello,Server!");
// 行分隔符,写入结束标记
bufferedWriter.newLine();
// 刷新缓冲区,写入数据通道
bufferedWriter.flush();

// 从数据通道读取数据
InputStream inputStream = socket.getInputStream();
// 字节输入流转换成字符输入流
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
System.out.println(bufferedReader.readLine());

// 关闭资源
bufferedReader.close();
bufferedWriter.close();
socket.close();

7. TCP 文件上传

Server

package upload;

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

/**
 * @author Spring-_-Bear
 * @version 2021-11-16 09:40
 */
public class Server 
    public static void main(String[] args) 
        Socket socket = null;
        InputStream inputStream = null;
        ServerSocket serverSocket = null;
        OutputStream outputStream = null;
        BufferedWriter bufferedWriter = null;
        ByteArrayOutputStream byteArrayOutputStream = null;
        BufferedOutputStream bufferedOutputStream = null;

        try 
            // 监听端口,等待连接
            serverSocket = new ServerSocket(6666);
            System.out.println("服务器已启动,等待连接···");
            socket = serverSocket.accept();

            // 文件大小,单位为字节
            long fileSize = 0;
            // 文件保存路径
            File fileSavePath = new File("C:\\\\Users\\\\Admin\\\\Desktop\\\\temp.jpg");

            // 从数组通道读取文件字节数组
            int readLen;
            byte[] buffer = new byte[1024];
            inputStream = socket.getInputStream();
            byteArrayOutputStream = new ByteArrayOutputStream();
            System.out.println("文件读取中···");
            while ((readLen = inputStream.read(buffer)) != -1) 
                byteArrayOutputStream.write(buffer, 0, readLen);
                fileSize += readLen;
            
            System.out.println("文件读取成功,总大小为 " + fileSize + " bytes!");
            // 将 byteArrayOutputStream 中的数据转换为字节数组(文件二进制数据)
            byte[] fileByteArray = byteArrayOutputStream.toByteArray();


            // 将文件字节数组保存到磁盘
            System.out.println("文件保存到本地中···");
            bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(fileSavePath));
            bufferedOutputStream.write(fileByteArray);
            System.out.println("文件保存到本地成功!保存路径为:" + fileSavePath);

            // 向客户端反馈文件下载保存成功信息
            outputStream = socket.getOutputStream();
            bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
            System.out.print("发送反馈信息到客户端··· ");
            bufferedWriter.write("文件接收成功,下载保存完成!");
            bufferedWriter.newLine();
            bufferedWriter.flush();
            System.out.println("消息发送成功!");
         catch (IOException e) 
            e.printStackTrace();
         finally 
            try 
                bufferedWriter.close();
                outputStream.close();
                bufferedOutputStream.close();
                byteArrayOutputStream.close();
                inputStream.close();
                socket.close();
                serverSocket.close();
             catch (IOException e) 
                e.printStackTrace();
            
        
    

Client

package upload;

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

/**
 * @author Spring-_-Bear
 * @version 2021-11-16 09:40
 */
public class Client 
    public static void main(String[] args) 
        Socket socket = null;
        InputStream inputStream = null;
        OutputStream outputStream = null;
        BufferedReader bufferedReader = null;
        BufferedInputStream bufferedInputStream = null;
        ByteArrayOutputStream byteArrayOutputStream = null;

        try 
            // 文件大小,以字节为单位
            int fileSize = 0;
            // 文件路径
            File filePath = new File("C:\\\\Users\\\\Admin\\\\Desktop\\\\fishing.jpg");

            // 从磁盘读取文件,并存入文件字节数组
            int readLen;
            byte[] buf = new byte[1024];
            byteArrayOutputStream = new ByteArrayOutputStream();
            bufferedInputStream = new BufferedInputStream(new FileInputStream(filePath));
            System.out.println("文件读入中···");
            while ((readLen = bufferedInputStream.read(buf)) != -1) 
                // 将从文件读取到的二进制数据写进字节数组输出流(byteArrayOutputStream)
                byteArrayOutputStream.write(buf, 0, readLen);
                fileSize += readLen;
            
            System.out.println("文件读入成功,文件大小为:" + fileSize + " bytes!");
            // 将得到的 byteArrayOutputStream 转换为一个字符数组
            byte[] fileByteArray = byteArrayOutputStream.toByteArray();

            // 将字节数组写入数据通道
            socket = new Socket(InetAddress.getLocalHost(), 6666);
            outputStream = socket.getOutputStream();
            System.out.println("文件发送到服务器中···");
            outputStream.write(fileByteArray);
            socket.shutdownOutput();
            System.out.println("文件发送到服务器成功!");

            // 接送服务器端发送的反馈信息并打印
            System.out.print("接收到的服务器信息:");
            inputStream = socket.getInputStream();
            bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            System.out.println(bufferedReader.readLine());
         catch (IOException e) 
            e.printStackTrace();
         finally 
            try 
                bufferedReader.close();
                inputStream.close();
                outputStream.close();
                byteArrayOutputStream.close();
                bufferedInputStream.close();
                socket.close();
             catch (IOException e) 
                e.printStackTrace();
            
        
    

8. TCP 文件下载

Server

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

/**
 * 服务端:将客户端请求的文件传输到客户端
 *
 * @author Spring-_-Bear
 * @version 2021-11-02 09:57
 */
public class FileServer 
    byte[] fileData = null;
    String requestFileName = null;
    ArrayList<String> fileNameList = new ArrayList<>();
    File filePath = new File("C:\\\\Users\\\\Admin\\\\Desktop\\\\sourceFile");

    Socket socket = null;
    ServerSocket serverSocket = null;
    InputStream inputStream = null;
    BufferedInputStream bufferedInputStream = null;

    public static void main(String[] args) 
        FileServer server = new FileServer();
        server.createAndReadFiles();
        server.startServer();
        server.receiveRequestNameFromClient();
        server.readFileFromDisk();
        server.transferFileToClient();
        try 
            server.socket.close();
            server.serverSocket.close();
            server.inputS

以上是关于[Java]Java 网络编程(Socket)和反射的主要内容,如果未能解决你的问题,请参考以下文章

java对象的序列化和反序列化

2018-07-25期 Java序列化和反序列化编程小案例

在Java中进行序列化和反序列化

(JSON) 序列化和反序列化,这个是啥意思呀?

Java序列化和反序列化

java基础序--列化和反序列化