当涉及到网络通信和数据传输时,Socket 是一个非常重要的概念。Socket 可以被看作是在不同设备之间进行通信的一种方式,它提供了一种简单而强大的机制,用于实现客户端和服务器之间的数据交换。
在本博客中,我们将探讨 Socket 的基本原理和使用方法,并通过一个具体的示例来展示如何使用 Socket 进行文件传输。Socket 实战传输文件的代码将帮助你深入理解如何利用 Socket 在客户端和服务器之间传输文件。
Socket 是一种用于网络通信的编程接口,它提供了一种机制,使得不同设备之间可以进行数据的传输和交换。通过 Socket,我们可以在客户端和服务器之间建立起双向的通信连接。
在网络通信中,Socket 可以被看作是两个进程之间的一条管道或通道,它负责在不同设备之间传递数据。每个 Socket 都有一个唯一的标识,由 IP 地址和端口号组成,用于定位网络中的特定节点。
Socket 的工作原理基于 TCP/IP 协议栈。在建立通信之前,服务器需要绑定到一个特定的 IP 地址和端口号上,并监听来自客户端的连接请求。客户端则通过指定服务器的 IP 地址和端口号来发起连接。一旦连接建立,客户端和服务器就可以通过 Socket 进行数据的发送和接收。
通过 Socket,我们可以实现各种类型的网络应用,如聊天程序、文件传输、远程控制等。它提供了一种简单而强大的方式,使得不同设备之间能够进行高效、可靠的数据交换。
在 Java 中,使用 Socket 进行网络编程非常方便。Java 提供了 java.net 包中的 Socket 类,它封装了底层的网络通信细节,提供了一组方法来创建、连接和管理 Socket。通过 Socket 类,我们可以轻松地实现客户端和服务器之间的数据传输,并处理网络通信中可能出现的各种情况。
public class SocketServerTest {
private static final int SERVER_PORT = 9019; // 服务端端口
private ServerSocket server;
private Socket socket;
private DataInputStream dis;
private FileOutputStream fos;
public SocketServerTest() throws Exception {
server = new ServerSocket(SERVER_PORT);
}
public void task() throws IOException {
Socket socket = server.accept(); // 等待客户端连接
System.out.println("ip:" + socket.getInetAddress() + " 连接成功");
try {
dis = new DataInputStream(socket.getInputStream());
// 读取文件名和长度
String fileName = dis.readUTF();
long fileLength = dis.readLong();
File directory = new File("D:\\file");//要保存传输文件的绝对路径地址
if (!directory.exists()) {
directory.mkdir();
}
File file = new File(directory.getAbsolutePath() + File.separatorChar + fileName);
file.createNewFile();
fos = new FileOutputStream(file);
System.out.println("fileName: " + fileName);
System.out.println("======== 开始接收文件 ========");
byte[] bytes = new byte[1024];
int length = 0;
while ((length = dis.read(bytes, 0, bytes.length)) != -1) {
fos.write(bytes, 0, length);
fos.flush();
}
System.out.println("======== 文件接收成功 ========");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (fos != null)
fos.close();
if (dis != null)
dis.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
try {
SocketServerTest server = new SocketServerTest(); // 启动服务端
server.task();
} catch (Exception e) {
e.printStackTrace();
}
}
}
这段代码是一个基于 Socket 的简单 Java 服务端实现,用于接收来自客户端的文件传输请求并保存文件到本地磁盘。下面对代码进行详细描述:
public class SocketClientTest extends Socket {
private final String SERVER_IP="192.168.3.114";
private final int SERVER_PORT=9019;
private Socket client;
private FileInputStream fis;
private DataOutputStream dos;
//创建客户端,并指定接收的服务端IP和端口号
public SocketClientTest() throws IOException {
this.client=new Socket(SERVER_IP,SERVER_PORT);
System.out.println("成功连接服务端..."+SERVER_IP);
}
public void panduan(String path) throws IOException {
File file = new File(path);
if (file.isDirectory()) {
String zipPath = zip(path);
sendFile(zipPath);
} else {
sendFile(path);
}
}
//向服务端传输文件
public void sendFile(String url) throws IOException {
File file=new File(url);
try {
fis = new FileInputStream(file);
dos = new DataOutputStream(client.getOutputStream());//client.getOutputStream()返回此套接字的输出流
//文件名、大小等属性
dos.writeUTF(file.getName());
dos.flush();
dos.writeLong(file.length());
dos.flush();
// 开始传输文件
System.out.println("======== 开始传输文件 ========");
byte[] bytes = new byte[1024];
int length = 0;
while ((length = fis.read(bytes, 0, bytes.length)) != -1) {
dos.write(bytes, 0, length);
dos.flush();
}
System.out.println("======== 文件传输成功 ========");
}catch(IOException e){
e.printStackTrace();
System.out.println("客户端文件传输异常");
}finally{
fis.close();
dos.close();
}
}
private static String zip(String url) throws IOException {
File sourceFile = new File(url);
String fileName = sourceFile.getName() + ".zip";
String filepath = sourceFile.getParent() + File.separator + fileName;
FileOutputStream fos = new FileOutputStream(filepath);
ZipOutputStream zos = new ZipOutputStream(fos);
zipFile(sourceFile, fileName, zos);
zos.close();
fos.close();
System.out.println("文件/文件夹已压缩为:" + filepath);
return filepath;
}
private static void zipFile(File fileToZip, String fileName, ZipOutputStream zos) throws IOException {
if (fileToZip.isHidden()) {
return;
}
if (fileToZip.isDirectory()) {
if (fileName.endsWith("/")) {
zos.putNextEntry(new ZipEntry(fileName));
} else {
zos.putNextEntry(new ZipEntry(fileName + "/"));
}
zos.closeEntry();
File[] children = fileToZip.listFiles();
if (children != null) {
for (File childFile : children) {
zipFile(childFile, fileName + File.separator + childFile.getName(), zos);
}
}
return;
}
FileInputStream fis = new FileInputStream(fileToZip);
ZipEntry zipEntry = new ZipEntry(fileName);
zos.putNextEntry(zipEntry);
byte[] bytes = new byte[1024];
int length;
while ((length = fis.read(bytes)) >= 0) {
zos.write(bytes, 0, length);
}
fis.close();
}
public static void main(String[] args) {
try {
SocketClientTest client = new SocketClientTest(); // 启动客户端连接
client.panduan("D:\\ajax_rmz"); // 要传输的文件绝对路径地址
} catch (Exception e) {
e.printStackTrace();
}
}
}
这段代码是一个基于 Socket 的简单 Java 客户端实现,用于向服务端发送文件。下面对代码进行详细描述:
在这篇博客中,我们学习了一个基于 Socket 的文件传输示例。代码包括服务端和客户端两部分。
服务端代码创建了一个 Socket 服务器,并监听指定的端口。一旦有客户端连接成功,服务端开始接收来自客户端的文件数据。它首先读取文件名和文件大小等属性,并创建一个同名的空文件。然后,通过循环逐块地接收并写入客户端发送的文件数据。最后,服务端输出文件接收成功的提示信息。
客户端代码创建了一个 Socket 客户端,并与指定的服务端进行连接。根据用户提供的路径,客户端判断是传输文件还是目录。如果是目录,客户端将压缩整个目录为一个 zip 文件后再进行传输;如果是文件,直接传输该文件。客户端通过套接字的输出流,将文件名和大小等信息发送给服务端,然后按块读取文件数据并发送给服务端。
通过这个示例,我们了解到使用 Socket 进行简单文件传输的基本原理。我们学会了建立客户端和服务端的连接,使用输入流和输出流进行数据传输,以及处理文件的读取、写入和目录的压缩。
希望大家可以通过本文深入了解Socket 这一技术,祝大家在使用Socket 时能取得成功!