【发布时间】:2015-06-20 07:00:04
【问题描述】:
我正在尝试使用 TCP 开发一个简单的 Java 文件传输应用程序。 我目前的服务器代码如下:
package tcp.ftp;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class FTPServer {
public static void main(String[] args) {
new FTPServer().go();
}
void go() {
try {
ServerSocket server = new ServerSocket(2015);
System.out.println("server is running ....!");
while (true) {
Socket socket = server.accept();
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String file = reader.readLine();
System.out.println("file to be downloaded is : " + file);
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
while (true) {
int octet = bis.read();
if (octet == -1) {
break;
}
bos.write(octet);
}
bos.flush();
//bos.close();
}
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
使用上面我当前的服务器代码,下载无法按预期工作。上面的代码将文件的一部分发送到客户端,而不是整个文件。请注意,我使用了 flush 方法来刷新缓冲区。但是当我用 close() 方法替换 flush() 方法时,文件完全发送到客户端而没有任何丢失。谁能解释一下这种行为!
更新:这是我客户的代码:
package tcp.ftp;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
/**
*
* @author aaa
*/
public class FTPClient {
public static void main(String[] args) {
String file = "JasperReports-Ultimate-Guide-3.pdf";
try {
InetAddress address = InetAddress.getLocalHost();
Socket socket = new Socket(address, 2015);
System.out.println("connection successfully established ....!");
PrintWriter pw = new PrintWriter(socket.getOutputStream());
pw.println(file);
pw.flush();
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy" + file));
while (true) {
int octet = bis.read();
if (octet == -1) {
break;
}
bos.write(octet);
}
bos.flush();
System.out.println("file download is complete ...!");
} catch (UnknownHostException ex) {
System.out.println(ex.getMessage());
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
不使用 Socket 的另一种行为。使用以下代码将文件从源复制到目标:
public class CopieFile {
static void fastCopy(String source, String destination) {
try {
FileInputStream fis = new FileInputStream(source);
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream(destination);
BufferedOutputStream bos = new BufferedOutputStream(fos);
while (true) {
int octet = bis.read();
if (octet == -1) {
break;
}
bos.write(octet);
}
bos.flush();
} catch (FileNotFoundException ex) {
System.out.println(ex.getMessage());
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
public static void main(String[] args) throws IOException {
String source = "...";
String destination = "...";
fastCopy(source, destination);
}// end main
}// end class
上面的代码将文件从一个位置复制到另一个位置而不会造成任何损失。请注意,我没有关闭流。
【问题讨论】:
-
必须有未发送的字节并关闭全部发送(在缓冲区中)。尝试将flush放在write之后,这样每次写操作后都会flush。
-
为什么有两个
while (true)循环? -
你是如何阅读客户端上的内容的?只是一个猜测,但可能是所有数据都以任何一种方式发送,但是通过不关闭服务器上的流,客户端上的循环不会正常退出,导致它看起来好像没有收到所有数据。
标签: java sockets socket.io serversocket