我的问题是,在我的客户端中,dis.read()
正在返回-1
,导致它永远不会真正收到该文件。我唯一能想到的是因为我在本节之前使用了PrintWriter
和BufferedReader
,dis.read()
认为已经收到了所有数据。
客户代码:
public static void receiveFile(String serverAddress, int port, String fileName, String fileOut) throws IOException {
Socket client = new Socket(serverAddress, port);
client.setSoTimeout(5000);
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
BufferedReader input = new BufferedReader(new InputStreamReader(client.getInputStream()));
try {
out.println("101|" + fileName + "\n");
if (input.readLine().equals("201")) {
int br;
byte[] data = new byte[4096];
DataInputStream dis = new DataInputStream(client.getInputStream());
FileOutputStream fos = new FileOutputStream(fileOut);
while ((br = dis.read(data, 0, data.length)) != -1){
fos.write(data, 0, br);
}
fos.close();
dis.close();
}
} catch (SocketTimeoutException ste) {
ste.printStackTrace();
client.close();
}
}
服务器代码:
private void sendFile(String filename, Socket client) throws IOException {
int br;
byte[] data = new byte[4096];
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
out.println("201\n");
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
FileInputStream fis = new FileInputStream(MeshFS.properties.getProperty("repository") + filename);
while ((br = fis.read(data, 0, data.length)) != -1) {
dos.write(data, 0, br);
dos.flush();
}
fis.close();
dos.close();
}
private String receiveRequest(Socket client) {
String requestPart;
String requestFull = "";
try {
BufferedReader input = new BufferedReader(new InputStreamReader(client.getInputStream()));
while (((requestPart = input.readLine()) != null) && (requestFull.length() < 2048)) {
if (requestPart.equals("")) break;
requestFull = requestFull + requestPart;
}
return requestFull;
} catch (IOException ioe) {
return requestFull;
}
}
private void processRequest(String request, Socket out) {
if (request != null) {
try {
String[] requestParts = request.split("\\|");
if (requestParts[0].equals("101")) { //101:Get file
sendFile(requestParts[1], out);
} else {
badRequest(out, request);
}
} catch (Exception e) {
badRequest(out, request);
e.printStackTrace();
}
}
}
public void run() {
while (!Thread.interrupted()) {
try {
server.setSoTimeout(1000);
Socket client = server.accept();
client.setSoTimeout(timeout);
processRequest(receiveRequest(client), client);
client.close();
} catch (SocketTimeoutException ste) {
} catch (IOException io) {
io.printStackTrace();
}
}
System.out.println("Socket closed");
}
我有什么遗漏或遗忘的内容吗?我不是在说些什么或者没有清理什么?
答案 0 :(得分:1)
好吧,我猜我发现了这个错误。我做了一些实验,发现如果多个对象试图从中读取,InputStream
表现得很奇怪。在您的情况下,您的客户BufferedReader
方法中的DataInputStream
和receiveFile
很可能会通过尝试从同一inputStream
读取来导致问题。我建议您使用DataInputStream
来阅读第一行,这样您就不必创建BufferedReader
。即使DataInputStream.readLine()
方法已被弃用,但在您的情况下仍然可以做得很好。
我编辑了客户端receiveFile
方法,以使用DataInputStream
来读取第一行。希望它有效!
public static void receiveFile(String serverAddress, int port, String fileName, String fileOut) throws IOException {
Socket client = new Socket(serverAddress, port);
client.setSoTimeout(5000);
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
DataInputStream dis = new DataInputStream(client.getInputStream());
try {
out.println("101|" + fileName + "\n");
if (dis.readLine().equals("201")) {
int br;
byte[] data = new byte[4096];
FileOutputStream fos = new FileOutputStream(fileOut);
while ((br = dis.read(data, 0, data.length)) != -1){
fos.write(data, 0, br);
}
fos.close();
dis.close();
}
} catch (SocketTimeoutException ste) {
ste.printStackTrace();
client.close();
}
}