[Java]Java 网络编程(Socket)和反射
Posted Spring-_-Bear
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Java]Java 网络编程(Socket)和反射相关的知识,希望对你有一定的参考价值。
一、网络编程
1. IP
- IP 地址概念:用于唯一标识网络中的每台计算机(主机)
- DOS 查看 IP 地址:ipconfig
- IPV4 用 4 字节共 32 位标识一个 IP 地址(点分十进制)
- IPV6 用 8 字节共 128 位标识一个 IP 地址
- IP 地址的组成:网络地址 + 主机地址
- 127.0.0.1 表示本机地址
- 127.0.0.1 表示本机地址
分类 | 表示方法 | 范围 |
---|---|---|
A | 0 + 7 位网络号 + 24 位主机号 | 0.0.0.0 ~ 127.255.255.255 |
B | 10 + 14 位网络号 + 16 位主机号 | 128.0.0.0 ~ 191.255.255.255 |
C | 110 + 21 位网络号 + 8 位主机号 | 192.0.0.0 ~ 223.255.255.255 |
D | 1110 + 28 位多播组号 | 224.0.0.0 ~ 239.255.255.255 |
E | 11110 + 27 位留待后用 | 240.0.0.0 ~ 247.255.255.255 |
2. 域名、端口及网络协议
- 域名:将 IP 地址映射成域名(http 协议)
- 端口:用于标识计算机上特定的网络程序,以整数形式表示,范围是 0 ~ 65535,其中 0 ~ 1024 已被占用。常见的网络程序端口:ssh 22、ftp 21、smtp 25、http 80、tomcat 8080、mysql 3306、oracle 1521、sql server 1433
- TCP / IP(
Transmission Control Protocol / Internet Protocol
):传输控制协议 / 因特网互联协议,又名网络通讯协议
TCP/IP模型 | 对应协议 |
---|---|
应用层 | http、ftp、telnet、DNS··· |
传输层 | TCP、UDP··· |
网络层 | IP、ICMP、ARP··· |
物理 + 数据链路层 | Link |
3. TCP、UDP 及 Socket
- TCP(
Transmission Control Protocol
):在使用 TCP 协议前,须先建立 TCP 连接,形成传输数据通道;传输前,采用 ”三次握手“ 方式建立连接,传输可靠;TCP 协议进行通信的两个应用程序:客户端、服务端;在连接中可进行大量数据的传输;传输完毕,需释放已建立的连接,效率较低- UDP(
User Data Protocol
):将数据、源、目的封装成数据包,不需要建立连接,传输不可靠,无需释放资源,速度快;每个数据包的大小限制在 64K 以内- 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)和反射的主要内容,如果未能解决你的问题,请参考以下文章