java - 使用 Java Socket 和 java.nio.file.Files.copy 发送文件
问题描述
我正在尝试制作一个简单的服务器/客户端应用程序来发送消息和文件。
我的客户端首先发送文件名,然后是文件本身,最后等待服务器的响应。
我的服务器相反,读取文件名,读取文件,发送响应。
问题是客户端卡在String response = dataInputStream.readUTF();
服务器卡在Files.copy(Paths.get(fileName), dataOutputStream);
我试图String response = dataInputStream.readUTF();
从客户端中删除,没有它它可以正常工作。有人可以帮我理解为什么我readUtf()
在发送文件后会卡住吗?
谢谢
这是我的客户
public static void main(String[] args) throws IOException {
String fileName = "hello.txt";
try (Socket clientSocket = new Socket(HOST, PORT)) {
DataInputStream dataInputStream = new DataInputStream(clientSocket.getInputStream());
DataOutputStream dataOutputStream = new DataOutputStream(clientSocket.getOutputStream());
dataOutputStream.writeUTF(fileName);
Files.copy(Paths.get(fileName), dataOutputStream);
String response = dataInputStream.readUTF();
LOGGER.info(response);
}
}
这是我的服务器
public static void main(String args[]) throws IOException {
try (ServerSocket ss = new ServerSocket(PORT)) {
Socket clientSocket = ss.accept();
DataOutputStream dataOutputStream = new DataOutputStream(clientSocket.getOutputStream());
DataInputStream dataInputStream = new DataInputStream(clientSocket.getInputStream());
String fileName = dataInputStream.readUTF();
Files.copy(dataInputStream, Paths.get(fileName));
dataOutputStream.writeUTF("New file saved");
}
}
解决方案
Here is my entire working sample of sending files from client to server. I am not sure particularly best when I was using Files.copy(...) on server I was getting stuck so you can check I have added boolean condition if the read is less that buffer size then there is no item present in the stream hence exit and close the file.
package com.company.socket;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
class SocketClient {
public static void main(String[] args) {
Thread clientThread = new Thread(new Runnable() {
@Override
public void run() {
try (Socket serverSocket = new Socket("localhost", 5000)) {
final DataOutputStream outputStream = new DataOutputStream(serverSocket.getOutputStream());
final BufferedReader br = new BufferedReader(new InputStreamReader(serverSocket.getInputStream()));
Files.copy(Path.of("hello.txt"), serverSocket.getOutputStream());
outputStream.flush();
System.out.println("file sent from client");
String content = null;
while ((content = br.readLine()) != null) {
System.out.println("Client response: " + content);
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
clientThread.start();
}
}
public class SocketServer {
public static void main(String[] args) throws InterruptedException, IOException {
final Thread serverThread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Started server");
List<Socket> clients = new ArrayList<>();
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Server shutdown!");
final List<String> collect = clients.stream()
.map(socket -> {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
return "Closed client: " + socket.getInetAddress().getHostAddress();
})
.collect(Collectors.toList());
collect.forEach(System.out::println);
}
}));
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(5000);
} catch (IOException e) {
e.printStackTrace();
}
while (true) {
try (Socket client = serverSocket.accept()) {
clients.add(client);
System.out.println("CLient connected: " + client.getInetAddress().getHostAddress() + ":" + client.getPort());
client.getOutputStream().write("Hello from server!".getBytes());
client.getOutputStream().flush();
final InputStream inputStream = client.getInputStream();
System.out.println("copyingReceiving file on server");
copyFile(inputStream);
System.out.println("File received successfully");
client.getOutputStream().write("\nFile received successfully".getBytes());
client.getOutputStream().flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
void copyFile(InputStream inputStream) throws IOException {
final byte[] buffer = new byte[2048];
final FileOutputStream outputStream = new FileOutputStream("file-" + UUID.randomUUID().toString() + ".txt");
int length = 0;
while ((length = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, length);
outputStream.flush();
if (length < buffer.length) break;
}
outputStream.close();
}
});
serverThread.start();
}
}
Server output
Started server
CLient connected: 127.0.0.1:38118
copyingReceiving file on server
File received successfully
Client output
file sent from client
Client response: Hello from server!
Client response: File received successfully
推荐阅读
- sql - 如何从今天开始从 DB2 获取过去 7 天(1 周)的记录
- c - 在本地测试 TCP/IP 服务器
- java - 无法从片段内部刷新 recyclveiw?
- ios - 按字母顺序将 NSMutableArray 数据动态排序到 NSDictionary
- c++ - 如何为每个循环传递一个成员函数?
- python - 识别 sqlalchemy.exc.OperationalError
- hadoop - Hive 中的数据透视表并为唯一组合创建多个列
- firebase - iPhone X 上没有出现通知气泡
- javascript - 从 ajax 调用返回到 django 视图的清洁日期字段
- ios - 无法接收任何用户登录的弹出窗口或提示