通过套接字将图像从android客户端发送到Java服务器时数据丢失
我正在尝试将我的图像从android客户端发送到Java服务器。我发送的图像大小约为99kb,但服务器的读取总是少一些kb,有时为98,有时为96,以此类推。我想知道数据丢失的原因,以及如何以正确的方式发送图像。请帮忙:) 代码: 服务器(接收图像): 编辑 问题已解决,工作代码如下: 客户端:通过套接字将图像从android客户端发送到Java服务器时数据丢失,java,android,sockets,networking,Java,Android,Sockets,Networking,我正在尝试将我的图像从android客户端发送到Java服务器。我发送的图像大小约为99kb,但服务器的读取总是少一些kb,有时为98,有时为96,以此类推。我想知道数据丢失的原因,以及如何以正确的方式发送图像。请帮忙:) 代码: 服务器(接收图像): 编辑 问题已解决,工作代码如下: 客户端: public void sendImage(File file){ try { DataOutputStream out
public void sendImage(File file){
try {
DataOutputStream out = new DataOutputStream(
socket.getOutputStream());
out.writeChar('I');
DataInputStream dis = new DataInputStream(new FileInputStream(file));
ByteArrayOutputStream ao = new ByteArrayOutputStream();
int read = 0;
byte[] buf = new byte[1024];
while ((read = dis.read(buf)) > -1) {
ao.write(buf, 0, read);
}
out.writeLong(ao.size());
out.write(ao.toByteArray());
out.flush();
out.close();
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
服务器端:
if(input =='I'){
DataInputStream dis = new DataInputStream(clientSocket.getInputStream());
long length = dis.readLong();
File to = new File("filename.jpg");
DataOutputStream dos = new DataOutputStream(
new FileOutputStream(to));
byte[] buffer = new byte[1024];
int len, current = 0;
System.out.println(length);
while ( current != length) {
len = dis.read(buffer);
dos.write(buffer, 0, len);
current += len;
System.out.println(current);
}
dis.close();
dos.close();
}
作为起点,在客户端,您还需要一个循环来读取本地映像,因为您确定
bis.read(byteArray,0,byteArray.length);
。。。真的在阅读整个图像吗?因此,您还需要一个循环,就像在服务器端一样。作为起点,在客户端,您还需要一个循环来读取本地映像,因为您确定
bis.read(byteArray,0,byteArray.length);
。。。真的在阅读整个图像吗?因此,您还需要一个服务器端的循环。根据我个人的经验,PrintWriter和缓冲区不能很好地协同工作。。 作为缓冲区,在您告诉它之前尝试读取数据,它可能会“窃取”不应该这样做的数据。例如,如果您使用任何类型的缓冲读取器来读取服务器端的输入,则缓冲区将在输入图像的“开始”处窃取某些部分,因为它认为这只是另一行。您可以尝试改用DataInputStream和DataOutputStream 客户:
public void sendImage(File file) {
try {
DataOutputStream out = new DataOutputStream(
socket.getOutputStream());
out.writeChar('I'); // as image,
DataInputStream dis = new DataInputStream(new FileInputStream(file));
ByteArrayOutputStream ao = new ByteArrayOutputStream();
int read = 0;
byte[] buf = new byte[1024];
while ((read = dis.read(buf)) > -1) {
ao.write(buf, 0, read);
}
out.writeLong(ao.size());
out.write(ao.toByteArray());
out.flush();
out.close();
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
服务器:
// assuming folder structure exists.
public void readImage(Socket s, File to) throws IOException {
DataInputStream dis = new DataInputStream(s.getInputStream());
char c = dis.readChar();
if (c == 'I') {
long length = dis.readLong();
DataOutputStream dos = new DataOutputStream(
new FileOutputStream(to));
byte[] buffer = new byte[1024];
int len;
while ((len = dis.read(buffer)) != -1) {
dos.write(buffer, 0, len);
}
dis.close();
dos.close();
}
}
根据我个人的经验,PrintWriter和Buffers不能很好地协同工作。。 作为缓冲区,在您告诉它之前尝试读取数据,它可能会“窃取”不应该这样做的数据。例如,如果您使用任何类型的缓冲读取器来读取服务器端的输入,则缓冲区将在输入图像的“开始”处窃取某些部分,因为它认为这只是另一行。您可以尝试改用DataInputStream和DataOutputStream 客户:
public void sendImage(File file) {
try {
DataOutputStream out = new DataOutputStream(
socket.getOutputStream());
out.writeChar('I'); // as image,
DataInputStream dis = new DataInputStream(new FileInputStream(file));
ByteArrayOutputStream ao = new ByteArrayOutputStream();
int read = 0;
byte[] buf = new byte[1024];
while ((read = dis.read(buf)) > -1) {
ao.write(buf, 0, read);
}
out.writeLong(ao.size());
out.write(ao.toByteArray());
out.flush();
out.close();
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
服务器:
// assuming folder structure exists.
public void readImage(Socket s, File to) throws IOException {
DataInputStream dis = new DataInputStream(s.getInputStream());
char c = dis.readChar();
if (c == 'I') {
long length = dis.readLong();
DataOutputStream dos = new DataOutputStream(
new FileOutputStream(to));
byte[] buffer = new byte[1024];
int len;
while ((len = dis.read(buffer)) != -1) {
dos.write(buffer, 0, len);
}
dis.close();
dos.close();
}
}
这可能是服务器写入图像的方式吗?也许会剥离一些元数据或其他什么?随便说说吧……恐怕我不知道。奇怪的是,当我用bitmap.compress方法(但我不想使用bitmap)发送图像时,图像安全到达。我想知道压缩版本是否也会像您的服务器“可能”那样剥离它?我看到您正在读取服务器上的字节数。但你不是在客户机上写这个号码。服务器读取图像的第一部分,并试图将其解释为要接收的数据长度。不,我不这样认为:P图像并没有被真正压缩(我认为它不是:P),因为我设置了100%的质量-类似这样:压缩(Bitmap.CompressFormat.JPG,100,stream)这可能是您的服务器编写图像的方式吗?也许会剥离一些元数据或其他什么?随便说说吧……恐怕我不知道。奇怪的是,当我用bitmap.compress方法(但我不想使用bitmap)发送图像时,图像安全到达。我想知道压缩版本是否也会像您的服务器“可能”那样剥离它?我看到您正在读取服务器上的字节数。但你不是在客户机上写这个号码。服务器读取图像的第一部分,并试图将其解释为要接收的数据长度uhh,不,我不这么认为:P图像并没有被真正压缩(我认为它不是:P),因为我设置了100%的质量-类似这样:压缩(Bitmap.CompressFormat.JPG,100,stream),如lipido所述,read可能不会一次返回所有字节,您需要检查返回的实际大小。如果低于您的要求,请重新阅读。基本上是把整个读取过程放在一个循环中。不幸的是,这与此无关。我已经检查过几次了,客户端的read方法总是返回正确的字节数。然而,您需要一个循环,并且需要在另一端使用相同的循环。read()的约定仅用于传输一个或多个字节。你不能依赖你观察到的行为。正如lipido提到的,read可能不会一次返回所有字节,你需要检查返回的实际大小。如果低于您的要求,请重新阅读。基本上是把整个读取过程放在一个循环中。不幸的是,这与此无关。我已经检查过几次了,客户端的read方法总是返回正确的字节数。然而,您需要一个循环,并且需要在另一端使用相同的循环。read()的约定仅用于传输一个或多个字节。您不能依赖您观察到的行为。您不“信任文件目标存在”。您正在使用“new FileOutputStream()”创建它。您仅假设目录存在。您不“信任文件目标存在”。您正在使用“new FileOutputStream()”创建它。您只是假设目录存在。