通过套接字发送时文件损坏
File corrupted while sending through socket
我只是想从一个套接字发送一些文件,我能够在没有任何中断的情况下发送这些文件:无论大小文件是小还是大,这都没有关系,它就像一个魅力一样发送。
但我遇到的问题是我发送的文件已损坏,即无法像音频或视频那样播放。我已经完成 this 但没有帮助。
我使用的代码如下。
服务器端:
File file = new File(
Environment.getExternalStorageDirectory(),
"testingFile.mp4");
byte[] mybytearray = new byte[4096];
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
OutputStream os;
DataOutputStream dos = null;
try {
os = socket.getOutputStream();
dos = new DataOutputStream(os);
dos.writeUTF(file.getName());
dos.writeLong(mybytearray.length);
int read;
while ((read = dis.read(mybytearray)) != -1) {
dos.write(mybytearray, 0, read);
}
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if (dos != null) {
dos.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
和客户端:
File file = new File(
Environment.getExternalStorageDirectory(),
"TEST SUCCESS.mp4");
InputStream in = null;
int bufferSize;
try {
bufferSize = socket.getReceiveBufferSize();
in = socket.getInputStream();
DataInputStream clientData = new DataInputStream(in);
String fileName = clientData.readUTF();
System.out.println(fileName);
OutputStream output = new FileOutputStream(
file);
byte[] buffer = new byte[bufferSize];
int read;
while ((read = clientData.read(buffer)) != -1) {
output.write(buffer, 0, read);
}
output.flush();
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (in != null) {
in.close();
}
}
提前致谢。
所以在评论中的对话之后,@MarquisofLorne 告诉我删除我在服务器端代码中编写的行。即从服务器端代码中删除此行:
dos.writeLong(mybytearray.length);
或者在客户端代码中写下这行代码:
long sizeOfFile = clientData.readLong();
它解决了问题。
服务器端
您的代码发送缓冲区长度 (4096),这是一个错误。
它应该发送文件长度。
File file = new File( ... );
try {
//dos.writeLong(mybytearray.length);
dos.writeLong(file.length());
}
客户端
服务器发送两个元数据
- 文件名(F字节,utf-8编码)
- 文件长度(8 字节)
然后发送全部内容(N字节)
但是客户端代码忽略文件长度(8字节),只读取文件名和内容N字节
in = socket.getInputStream();
DataInputStream clientData = new DataInputStream(in);
String fileName = clientData.readUTF(); // ok read F bytes
// missing readLong(..) 8 bytes
// long fileLen = clientData.readLong(); <= read file length before reading contents
// read N bytes, but first 8 bytes are file length, which are written into file.
int read;
while ((read = clientData.read(buffer)) != -1) {
output.write(buffer, 0, read);
}
不要依赖-1
您的代码在 while
循环
中继续依赖 -1
while ((read = dis.read(mybytearray)) != -1) {
dos.write(mybytearray, 0, read);
}
while ((read = clientData.read(buffer)) != -1) {
output.write(buffer, 0, read);
}
-1
表示异常状态
因为服务器知道文件的确切大小并写出文件,所以客户端应该从流中读取准确的字节长度。
如果服务器发送 1234 字节,当客户端从 clientData.read(..)
读取 -1 时,它无法从流中读取内容,而不是流的结尾。
我只是想从一个套接字发送一些文件,我能够在没有任何中断的情况下发送这些文件:无论大小文件是小还是大,这都没有关系,它就像一个魅力一样发送。
但我遇到的问题是我发送的文件已损坏,即无法像音频或视频那样播放。我已经完成 this 但没有帮助。
我使用的代码如下。
服务器端:
File file = new File(
Environment.getExternalStorageDirectory(),
"testingFile.mp4");
byte[] mybytearray = new byte[4096];
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
OutputStream os;
DataOutputStream dos = null;
try {
os = socket.getOutputStream();
dos = new DataOutputStream(os);
dos.writeUTF(file.getName());
dos.writeLong(mybytearray.length);
int read;
while ((read = dis.read(mybytearray)) != -1) {
dos.write(mybytearray, 0, read);
}
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if (dos != null) {
dos.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
和客户端:
File file = new File(
Environment.getExternalStorageDirectory(),
"TEST SUCCESS.mp4");
InputStream in = null;
int bufferSize;
try {
bufferSize = socket.getReceiveBufferSize();
in = socket.getInputStream();
DataInputStream clientData = new DataInputStream(in);
String fileName = clientData.readUTF();
System.out.println(fileName);
OutputStream output = new FileOutputStream(
file);
byte[] buffer = new byte[bufferSize];
int read;
while ((read = clientData.read(buffer)) != -1) {
output.write(buffer, 0, read);
}
output.flush();
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (in != null) {
in.close();
}
}
提前致谢。
所以在评论中的对话之后,@MarquisofLorne 告诉我删除我在服务器端代码中编写的行。即从服务器端代码中删除此行:
dos.writeLong(mybytearray.length);
或者在客户端代码中写下这行代码:
long sizeOfFile = clientData.readLong();
它解决了问题。
服务器端
您的代码发送缓冲区长度 (4096),这是一个错误。
它应该发送文件长度。
File file = new File( ... );
try {
//dos.writeLong(mybytearray.length);
dos.writeLong(file.length());
}
客户端
服务器发送两个元数据
- 文件名(F字节,utf-8编码)
- 文件长度(8 字节)
然后发送全部内容(N字节)
但是客户端代码忽略文件长度(8字节),只读取文件名和内容N字节
in = socket.getInputStream();
DataInputStream clientData = new DataInputStream(in);
String fileName = clientData.readUTF(); // ok read F bytes
// missing readLong(..) 8 bytes
// long fileLen = clientData.readLong(); <= read file length before reading contents
// read N bytes, but first 8 bytes are file length, which are written into file.
int read;
while ((read = clientData.read(buffer)) != -1) {
output.write(buffer, 0, read);
}
不要依赖-1
您的代码在 while
循环
-1
while ((read = dis.read(mybytearray)) != -1) {
dos.write(mybytearray, 0, read);
}
while ((read = clientData.read(buffer)) != -1) {
output.write(buffer, 0, read);
}
-1
表示异常状态
因为服务器知道文件的确切大小并写出文件,所以客户端应该从流中读取准确的字节长度。
如果服务器发送 1234 字节,当客户端从 clientData.read(..)
读取 -1 时,它无法从流中读取内容,而不是流的结尾。