2011-10-01 83 views
3

我试图通过一个套接字从我的Android设备发送图像到我的电脑。问题是我的计算机上的输入流会读取每一个字节,但最后一组字符。我曾尝试微调字节数组下来并发送它,我手写了-1到的OutputStream多次,但从来没有的InputStream读取-1。它只是挂起等待数据。我也试着不关闭流或插座,看看它是否是某种形式的计时问题,但没有正常工作。的InputStream没有收到EOF

客户端(Android手机)

//This has to be an objectoutput stream because I write objects to it first 
InputStream is = An image's input stream android 
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream()); 
objectOutputStream.writeObject(object); 
objectOutputStream.flush(); 

byte[] b = new byte[socket.getSendBufferSize()]; 
int read = 0; 
while ((read = is.read(b)) != -1) { 
    objectOutputStream.write(b, 0, read); 
    objectOutputStream.flush(); 
    b = new byte[socket.getSendBufferSize()]; 
} 
//Tried manually writing -1 and flushing here 
objectOutputStream.close(); 
is.close(); 
socket.close(); 

服务器端(电脑)对象输入流之后的这段代码发生在发送的对象读取。它只是开始读取文件时开始发送

File loc = Location of where the file is stored on the computer 
loc.createNewFile(); 
FileOutputStream os = new FileOutputStream(loc); 
Socket gSocket = The socket 
ObjectInputStream gInputStream = Object Input stream created from the sockets input stream already used to read in the previous objects 

byte[] b = new byte[gSocket.getReceiveBufferSize()]; 
int read = 0; 
while ((read = gInputStream.read(b)) != -1) { 
    os.write(b, 0, read); 
    os.flush(); 
    b = new byte[gSocket.getReceiveBufferSize()]; 
} 

os.close(); 

此代码从未在读取-1,即使我写-1直接冲洗流。结果是java.net.SocketException异常:当从机器人装置中的流或关闭套接字连接复位。图片几乎完全发送,但图片的最后一个像素是灰色的。我还甚至直接使用输出/输入流从插座上,而不是使用已经创建的ObjectInputStream/ObjectOutputStream的尝试,它仍然无法正常工作。

+0

有一件事值得注意,你只需要创建一次'byte []'。使用'read(b)'意味着你从0开始读入数组,它返回读入的字节数。随后的调用只是覆盖以前的任何数据。 –

+0

我实际上重新初始化数组以始终是套接字当前支持的大小。所以我不需要抵消。 –

+0

套接字当前支持的大小不会改变,除非您更改它,并且对于您的应用程序缓冲区使用相同的大小没有特别的好处。 – EJP

回答

8

首先,我想你是误会EOF(-1)的意思。这并不意味着服务器写了-1,这意味着服务器关闭了流。

我认为你的主要问题是,虽然在服务器和客户端在一个循环正在阅读,并没有得到他们关闭流点。他们陷入僵局 - 两个人都在等待另一个先关闭。

您的客户端:

Your client

您的服务器:

Your server

如果你知道你有没有更多的数据写入然后就关闭流。

+0

客户端的流完全结束并关闭流。这是服务器收到EOF异常的时候。 –

+1

@ user695992:您发布的代码显示客户端在关闭其流之前等待服务器关闭其流。 –

+0

它正在等待关闭的流是图像输入流。因此,客户端从图像输入流中一次读取一组字节并将其推出输出流。服务器一次从客户端读入一组字节,然后推送到文件的输出流。 –

3

既然你已经使用ObjectInputStreamObjectOutputStream,你可以利用各自readObjectwriteObject方法同时进行读/写整个对象。也许你可以发送/接收整个字节数组作为一个对象?

On your android:

1)byte [] imageBytes = ...; //包含图像

2)objectOutputStream.writeObject(imageBytes);

在计算机:

1)字节[] imageBytes =(字节[])的readObject();

2)得到imageBytes

球场的图像,你将不得不使用readObject从一个线程中,因为它会阻止。

+0

是的。这会阻止,但不幸的是我不能使用它,因为这些文件会导致内存不足的错误。完整对象的问题是你必须先将整个事物读入内存。尽管谢谢你的回应。 –

1

您正在撰写字节[]数组为对象,BUR读取字节。你应该阅读对象和铸造他们为byte []。EOS将导致抛出EOFException。