英文:
File corrupted while sending through socket
问题
以下是已翻译的内容:
我只是在尝试从套接字发送一些文件,我能够在没有任何中断的情况下发送这些文件:无论文件大小是小还是大,都没有关系,它都能顺利发送。
但我遇到的问题是,我发送的文件被损坏了,即它无法像音频或视频那样播放。我已经阅读了这个链接,但没有帮助。
我使用的代码如下。
服务器端:
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) {
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) {
e.printStackTrace();
} finally {
if (in != null) {
in.close();
}
}
提前致谢。
英文:
I am just trying to send some files from a socket and i am able to send those files without any interruption: also whether the size file is small or large that does not matter it sends like a charm.
But the problem in my case that is arising is the file that i sent is being corrupted, i.e. it is not playing like audio or video. I have already gone through this but it did not helped.
The code that I am using is below.
Server Side:
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();
}
}
And the Client Side :
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();
}
}
Thanks in advance.
答案1
得分: 1
所以在评论中的交谈之后,正如@MarquisofLorne所说,要从我的服务器端代码中删除我写的那行代码。即从服务器端代码中删除这行代码:
dos.writeLong(mybytearray.length);
或者在客户端代码中写入下面这行代码:
long sizeOfFile = clientData.readLong();
这解决了这个问题。
英文:
So after the conversations in comments and as @MarquisofLorne told to delete the line that i have written in my server side code. i.e either delete this line from server side code:
dos.writeLong(mybytearray.length);
or write this below line code in client side code:
long sizeOfFile = clientData.readLong();
It solves the problem.
答案2
得分: -1
服务器端
你的代码发送了缓冲区长度(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(); // 读取 F 字节的文件名
// 缺少 readLong(..) 8 字节
// long fileLen = clientData.readLong(); <= 在读取内容之前读取文件长度
// 读取 N 字节,但是前面的 8 字节是文件长度,应该先将其写入文件。
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 时,它无法从流中读取内容,而不是流的结尾。
英文:
Server Side
Your code sends buffer length(4096), which is a bug.
It should send file length.
File file = new File( ... );
try {
//dos.writeLong(mybytearray.length);
dos.writeLong(file.length());
}
Client Side
Server sends two meta data
- file name( F bytes, encoded by utf-8)
- file length (8 bytes)
And then sends entire contents( N bytes)
But client code ignores file length(8bytes), just reads file name and contents N bytes
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);
}
Don't rely on -1
Your codes keep relying on -1
in while
loop
while ((read = dis.read(mybytearray)) != -1) {
dos.write(mybytearray, 0, read);
}
while ((read = clientData.read(buffer)) != -1) {
output.write(buffer, 0, read);
}
-1
means abnormal state.
Because server knows the exact size of a file and writes out the file, client should read the exact length of bytes from stream.
If server send 1234 bytes, when client read -1 from clientData.read(..)
, it fails to read contents from stream, not end of stream.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论