我正在尝试从“服务器”发送图像,其目的是将图像发送到作为Android设备的“客户端”。之间的插座保持打开状态,图像不断出现。问题是:
在我的代码中:
-1
),它会在套接字关闭时停止; 起初我尝试发送2个BMP图像,其大小我知道(两个大小相同)。这是服务器代码:
public static void main(String[] args) {
try {
ServerSocket s = new ServerSocket(4488);
System.out.println("Waiting for a connection . . . . ");
Socket socket = s.accept();
System.out.println("Connected!");
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
Thread.sleep(2000);
File myImageFile = new File("c:\\1\\a.bmp");
FileInputStream fis = new FileInputStream(myImageFile);
byte[] data = new byte[(int) myImageFile.length()];
byte[] tmp = new byte[0];
byte[] myArrayImage = new byte[0];
int len = 0 ;
int total = 0;
while( (len = fis.read(data)) != -1 ) {
total += len;
tmp = myArrayImage;
myArrayImage = new byte[total];
System.arraycopy(tmp,0,myArrayImage,0,tmp.length);
System.arraycopy(data,0,myArrayImage,tmp.length,len);
}
//
fis.close();
dataOutputStream.write(myArrayImage);
dataOutputStream.flush();
Thread.sleep(2000);
myImageFile = new File("c:\\1\\b.bmp");
fis = new FileInputStream(myImageFile);
data = new byte[(int) myImageFile.length()];
tmp = new byte[0];
myArrayImage = new byte[0];
len = 0 ;
total = 0;
while( (len = fis.read(data)) != -1 ) {
total += len;
tmp = myArrayImage;
myArrayImage = new byte[total];
System.arraycopy(tmp,0,myArrayImage,0,tmp.length);
System.arraycopy(data,0,myArrayImage,tmp.length,len);
}
fis.close();
dataOutputStream.write(myArrayImage);
dataOutputStream.flush();
Thread.sleep(2000);
socket.close();
s.close();
以下是客户端代码:
@Override
public void run() {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
byte[] byteChunk = null;
int c;
if (_dataInputStream != null) {
while (true) {
try {
Thread.sleep(200);
} catch (Exception e) {
}
try {
byteChunk = new byte[1024];
while ((c = _dataInputStream.read(byteChunk)) != -1){
buffer.write(byteChunk, 0, byteChunk.length);
}
} catch (IOException e) {
e.printStackTrace();
}
final Bitmap bitmap = BitmapFactory.decodeByteArray(buffer.toByteArray(), 0, buffer.size());
if (bitmap != null) {
_handler.post(new Runnable() {
public void run() {
_iv.setImageBitmap(bitmap);
_iv.invalidate();
}
});
}
buffer.reset();
}
}
}
现在,正如我所说,客户端停留在while循环上,直到套接字关闭然后(无论我发送了多少图像,因为我在客户端创建了一个只适用于1个图像的bytearray)不断阅读第一张图片。
任何想法我做错了什么?
P.S。如果图像不是BMP,我在客户端代码中编写的解码会起作用吗?我要发送的真实图像是PNG。
答案 0 :(得分:0)
除非您使用某种机制来指示输入的结束,否则客户端无法知道何时停止从流中读取。
一个简单的修复方法是使用一个固定长度(四个字节,一个int就足以满足大多数图像)的标头,你写入流,告诉客户端下列数据的长度。然后,客户端在停止并等待其他标头或关闭流之前从流中读取该字节数。
另一种方法是使用文件结束分隔符来通知客户端已经遇到输入结束。
除非您在输入后关闭流,否则您将不得不在图像本身之外的流中编写一些其他数据(元数据)。
答案 1 :(得分:0)
只查看了您的客户端代码,但这不符合评论。你需要重新思考你在做什么;你的想法(我在我的第一次尝试时做同样的事情)是基于人的而不是基于计算机的。换句话说,你的代码对人类来说是 me 是有意义的,但我真的不知道为什么,这对计算机来说没有意义。
要点:你的while (true)
循环没有退出 - 它是无限的。我希望它能重复上次读到“位图”。
首先,我将摆脱sleep
代码。现在这个问题让人感到困惑,如果有所帮助,你可以稍后再回过头来。 (我认为它不会,你的读取将完成所有必要的阻塞。)然后,当读取完整的图像时,你需要一个图像结束标记或某些东西来阻止你读取循环。 (或者让它触发在这个循环内的图像处理代码。)
最后,您需要一个文件结束或图像结束标记来帮助您摆脱while (true)
循环。 (回到“主要观点”。)
答案 2 :(得分:0)
嗨,但如果您想阅读jpeg
文件,那么您可以使用此代码
byte[] bytes = new byte[1024 * 1024];
int count = 0;
do
{
count += in.read(bytes, count, bytes.length - count);
}while (!(count > 4 && bytes[count - 2] == (byte) -1 && bytes[count - 1] == (byte) -39));
但我无法理解如何阅读PNG
格式
答案 3 :(得分:0)
你可以先发送图像字节数组的大小,然后在while循环中读取字节,直到达到这样的大小:
DataInputStream in = conn.openDataInputStream();
// read a length first
int length = in.readInt();
if (length <= 0) {
throw new IOException("Can't read a length");
}
// read the image now
imgData = new byte[length];
length = 0;
while (length != imgData.length) {
int n = in.read(imgData, length, imgData.length - length);
if (n == -1) {
throw new IOException("Can't read a image data");
}
length += n;
}
in.close();
this is an edited version of this
注意图像的大小是int并且它有多个字节,那么你需要使用writeint。
答案 4 :(得分:-1)
如果您想发送PNG,请阅读一些有关格式(Wiki)的内容。每个块都是长度前缀的,因此您可以通过网络原始发送它并知道它何时完成!