如何解决通过套接字发送时文件损坏
我只是想从套接字发送一些文件,并且能够无中断地发送这些文件:还有大小文件的大小无关紧要,就像附件一样发送。
但是在我的情况下出现的问题是我发送的文件已损坏,即,它不能像音频或视频那样播放。我已经经历过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,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,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个字节)
但是客户端代码忽略文件长度(8bytes),仅读取文件名和内容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,read);
}
不要依赖-1
您的代码继续依靠-1
循环中的while
while ((read = dis.read(mybytearray)) != -1) {
dos.write(mybytearray,read);
}
while ((read = clientData.read(buffer)) != -1) {
output.write(buffer,read);
}
-1
表示异常状态。
由于服务器知道文件的确切大小并写出文件,因此客户端应从流中读取字节的确切长度。
如果服务器发送1234个字节,则当客户端从clientData.read(..)
读取-1时,它将无法从流而不是流的末尾读取内容。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。