获取“java.io.EOFException”通过套接字发送文件后
我正在尝试通过套接字实现基本通信,我现在拥有的是:
服务器开始监听套接字,
this.serverSocket_ = new ServerSocket(this.serverPort_); clientSocket = this.serverSocket_.accept();
客户端连接,服务器启动单独的线程与该客户端进行操作,
同时打开对象输出和输入流,
out = new ObjectOutputStream(clientSocket_.getOutputStream()); 出.flush(); in = new ObjectInputStream(clientSocket_.getInputStream());
客户端通过该流发送两个 i Double、String 和 Long(在每个之后刷新),
out.writeObject(conf_); 出.flush(); out.writeObject(supp_); 出.flush(); out.writeObject(separator_); 出.flush(); out.writeObject(new Long(dataFile_.length())); 出.flush();
服务器通过之前打开的流成功接收这些对象,
conf_ = (Double) in_.readObject(); support_ = (Double) in_.readObject(); 分隔符_ = (字符串) in_.readObject(); fileSize_ = (Long) in_.readObject();
现在是“困难的部分”,
客户端想要发送文件所以打开不同的输出流(不是对象输出流)并发送文件,
FileInputStream fis = new FileInputStream(dataFile_); BufferedInputStream bis = new BufferedInputStream(fis); OutputStream os = clientSocket_.getOutputStream(); while(当前<文件大小){ bytesRead = bis.read(mybytearray, 0, mybytearray.length); if (bytesRead >= 0) { os.write(mybytearray, 0, mybytearray.length); 当前+=字节读取; } ProgressBar_.setValue(当前); ProgressBar_.repaint(); } os.flush();
服务器接收文件(也使用简单输入流而不是 ObjectInputStream),
int bytesRead; 整数当前= 0; tmpFile_ = File.createTempFile("篮子分析", "rec.dat"); byte[] mybytearray = 新字节[文件大小]; 输入流 = clientSocket_.getInputStream(); FileOutputStream fos = new FileOutputStream(tmpFile_); BufferedOutputStream bos = new BufferedOutputStream(fos); bytesRead = is.read(mybytearray, 0, mybytearray.length); 当前=字节读取; 做 { bytesRead = is.read(mybytearray, 当前, (mybytearray.length - 当前)); if (字节读取>= 0) 当前+=字节读取; while ((bytesRead > -1) && (当前 < 文件大小)); bos.write(mybytearray, 0, 当前); bos.flush(); bos.close();
到目前为止一切正常,文件已收到,但现在服务器对该文件执行一些耗时的处理,然后发送将结果回复给客户,
String resp = new String("一些处理结果..."); out_.writeObject(resp); out_.flush();
客户端应该收到结果什么完成了整个通信,
String message = (String) in.readObject(); Console.info("服务器>" + 消息);
不幸的是,客户端的最后一步失败,但出现异常:
java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at basketAnalysis.client.Client.run(Client.java:74)
at java.lang.Thread.run(Unknown Source)
我希望客户端在发送文件后阻止等待服务器响应,但是发送文件后它突然结束并出现异常。我很确定我在简单流和对象流之间切换时做错了。
有谁知道我应该改变什么才能让它工作?
先感谢您!
I'm trying to implement basic communication through sockets, what I have now is:
server start's to listen on socket,
this.serverSocket_ = new ServerSocket(this.serverPort_); clientSocket = this.serverSocket_.accept();
client connects, and server starts separate thread to operate with that client,
both open Object output and input streams,
out = new ObjectOutputStream(clientSocket_.getOutputStream()); out.flush(); in = new ObjectInputStream(clientSocket_.getInputStream());
client sends two i Doubles, String and Long over that stream (flushes after each one),
out.writeObject(conf_); out.flush(); out.writeObject(supp_); out.flush(); out.writeObject(separator_); out.flush(); out.writeObject(new Long(dataFile_.length())); out.flush();
server succesfully receives those objects over previously opened streams,
conf_ = (Double) in_.readObject(); supp_ = (Double) in_.readObject(); separator_ = (String) in_.readObject(); fileSize_ = (Long) in_.readObject();
and now "the hard part",
clients wants to send a file so opens different output stream (not object output stream) and sends the file,
FileInputStream fis = new FileInputStream(dataFile_); BufferedInputStream bis = new BufferedInputStream(fis); OutputStream os = clientSocket_.getOutputStream(); while (current < fileSize) { bytesRead = bis.read(mybytearray, 0, mybytearray.length); if (bytesRead >= 0) { os.write(mybytearray, 0, mybytearray.length); current += bytesRead; } progressBar_.setValue(current); progressBar_.repaint(); } os.flush();
the server receives the file (also uses simple input stream instead ObjectInputStream),
int bytesRead; int current = 0; tmpFile_ = File.createTempFile("BasketAnalysis", "rec.dat"); byte[] mybytearray = new byte[fileSize]; InputStream is = clientSocket_.getInputStream(); FileOutputStream fos = new FileOutputStream(tmpFile_); BufferedOutputStream bos = new BufferedOutputStream(fos); bytesRead = is.read(mybytearray, 0, mybytearray.length); current = bytesRead; do { bytesRead = is.read(mybytearray, current, (mybytearray.length - current)); if (bytesRead >= 0) current += bytesRead; } while ((bytesRead > -1) && (current < fileSize)); bos.write(mybytearray, 0, current); bos.flush(); bos.close();
so far everything works fine, file is received, but now server performs some time consuming processing on that file after which sends response with whe results to client,
String resp = new String("Some processing result..."); out_.writeObject(resp); out_.flush();
the client is supposed to receive the result what finishes the whole communication,
String message = (String) in.readObject(); Console.info("server > " + message);
Unfortunately, that last step on client side fails with exception:
java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at basketAnalysis.client.Client.run(Client.java:74)
at java.lang.Thread.run(Unknown Source)
I want client to block on waiting for server response after sending the file, but it suddenly finishes with the exception after sending the file. I am pretty sure that I do something wrong with switching between simple streams and Object streams.
Does anybody know what should I change to haave it working?
Thank you in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为你的基本误解在这里:
这不会打开不同输出流 - 这将获得对您已经存在的相同输出流的另一个引用被包装在
ObjectOutputStream
中。如果您想要两个数据流,则需要打开两个单独的连接。I think your basic misunderstanding is here:
That doesn't open a different output stream - that will get another reference to the same output stream which you've already got wrapped in the
ObjectOutputStream
. If you want two streams of data, you'll need to open two separate connections.