我正在尝试通过Java套接字将文件从一个程序发送到另一个程序。我的代码基于this question。 问题是在托管服务器的Ubuntu机器上,发送的文件大小为0字节。代码已经在我的Windows笔记本电脑上的本地连接上工作,所以可能问题有与远程连接有关吗?
服务器代码:
int g = Integer.parseInt(in.readLine());
if(g > -1) {
InputStream fIn = client.getInputStream();
for(int i = 0; i < g; i++) {
String name = in.readLine();
byte[] bytes = new byte[16*1024];
File f = new File("plugins/" + name + ".jar");
if(!f.exists()) f.createNewFile();
FileOutputStream fOut = new FileOutputStream(f);
int count;
while ((count = fIn.read(bytes)) >= 0) {
fOut.write(bytes, 0, count);
}
fOut.flush();
fOut.close();
}
System.out.println("[" + client.getRemoteSocketAddress().toString() + "] added " + g + " new plugins.");
client.close();
}else{
client.close();
}
客户代码:
JFileChooser fd = new JFileChooser("C:\\");
fd.setFileSelectionMode(JFileChooser.FILES_ONLY);
fd.setMultiSelectionEnabled(true);
fd.setFileFilter(new FileNameExtensionFilter(null,"jar"));
int r = fd.showOpenDialog(null);
if(r == JFileChooser.APPROVE_OPTION) {
File[] files = fd.getSelectedFiles();
OutputStream fOut = sock.getOutputStream();
out.println(files.length);
for(File f : files) {
out.println(f.getName().split("\\.")[0]);
byte[] bytes = new byte[16 * 1024];
FileInputStream fIn = new FileInputStream(f);
int count;
while ((count = fIn.read(bytes)) >= 0) {
fOut.write(bytes, 0, count);
}
fIn.close();
}
}else{
out.println(-1);
}
sock.close();
答案 0 :(得分:0)
如评论中所述,您的代码中存在不同的问题。
要识别单个文件的结尾,您只需在用分号分隔的文件名后添加文件大小;
out.println(f.getName().split("\\.")[0] + "; size" + f.length());
在服务器端,你累积文件大小读/写停止读取文件的内容关闭它并读取下一行(文件名/文件大小)。
如评论中所述,存在不同的问题。
您使用fIn
和fOut
,但不清楚它们是如何定义的。
在客户端,您使用fOut
,而Socket OutputStream被命名为&#39; out&#39;。
在服务器端类似的事情。您从in
读取文件数,但之后从Socket获取InputStream(再次?)并将其用作fIn
。取决于您的in
可能有效还是无效。
同时从readLine
中读取来自InputStream
的行以及二进制内容也不是那么简单。在我的示例代码中,我使用了DataInputStream
,即使readLine
方法已被弃用。
示例还使用&#34;尝试使用资源&#34;语法,以确保在异常情况下所有资源(Streams,Sockets)都关闭。
示例没有说明如何处理服务器端的文件大小这取决于您。
该示例在一台计算机上完全可运行,并显示如何根据您的代码通过套接字复制单个文件。
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class ClientServerSocketExample {
private static class Server {
public void run() throws IOException {
try (ServerSocket serverSocket = new ServerSocket(41000, 10, InetAddress.getLocalHost())) {
try (Socket client = serverSocket.accept()) {
try (DataInputStream in = new DataInputStream(client.getInputStream())) {
int g = Integer.parseInt(in.readLine());
if(g > -1) {
for(int i = 0; i < g; i++) {
String[] filenameAndSize = in.readLine().split(";");
String name = filenameAndSize[0];
byte[] bytes = new byte[16*1024];
File f = new File("/tmp/" + name + ".jar");
if(!f.exists()) f.createNewFile();
try (FileOutputStream fOut = new FileOutputStream(f)) {
int count;
while ((count = in.read(bytes)) >= 0) {
fOut.write(bytes, 0, count);
}
fOut.flush();
}
}
System.out.println("[" + client.getRemoteSocketAddress().toString() + "] added " + g + " new plugins.");
}
}
}
}
}
}
private static class Client {
public void run() throws IOException {
try (Socket socket = new Socket()) {
socket.connect(new InetSocketAddress(InetAddress.getLocalHost(), 41000) );
sendFiles(socket);
}
}
private static void sendFiles(Socket sock) throws IOException {
File[] files = new File[]{new File("some.jar")};
OutputStream fOut = sock.getOutputStream();
PrintStream out = new PrintStream(fOut);
out.println(files.length);
for(File f : files) {
out.println(f.getName().split("\\.")[0] + "; size" + f.length());
byte[] bytes = new byte[16 * 1024];
try (FileInputStream fIn = new FileInputStream(f)) {
int count;
while ((count = fIn.read(bytes)) >= 0) {
out.write(bytes, 0, count);
}
out.flush();
}
}
}
}
public static void main(String ... args) throws IOException, InterruptedException {
new Thread(new Runnable() {
@Override
public void run() {
try {
new Server().run();
} catch (IOException ioe) {
System.out.println(ioe);
}
}
}).start();
System.out.println("Waiting for the Server to come up");
Thread.sleep(500);
new Client().run();
}
}
当客户端发送\r
作为新行分隔符并且文件以\n
开头时,此解决方案可能存在问题。服务器可能会将\n
计为行分隔符的一部分,并且文件将损坏(将丢失一个字节)。