【发布时间】:2013-07-11 04:12:26
【问题描述】:
我看到了一些关于这个的帖子,但我仍然找不到答案。
这是我的服务器与客户端交互的方式:
public void run () {
try {
//Read client request
InputStream is = server.getInputStream();
byte[] buff = new byte[1024];
int i;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while ((i = is.read(buff, 0, buff.length)) != -1) {
bos.write(buff, 0, i);
System.out.println(i + " bytes readed ("+bos.size()+")");
}
is.close();
is = null;
//Do something with client request
//write response
OutputStream os = server.getOutputStream();
os.write("server response".getBytes());
os.flush();
os.close();
os = null;
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
这是客户端:
public void run() {
try {
InetAddress serverAddr = null;
serverAddr = InetAddress.getByName("10.0.2.2");
socket = new Socket(serverAddr, 5000);
//Send Request to the server
OutputStream os = socket.getOutputStream();
os.write(jsonRequest.toString().getBytes("UTF-8"));
os.flush();
os.close();
os = null;
//Read Server Response
InputStream is = socket.getInputStream();
byte[] buff = new byte[1024];
int i;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while ((i = is.read(buff, 0, buff.length)) != -1) {
bos.write(buff, 0, i);
System.out.println(i + " bytes readed ("+bos.size()+")");
}
is.close();
is = null;
//Do something with server response
} catch (UnknownHostException uhe) {
sendCallbackError(uhe);
} catch (IOException ioe) {
sendCallbackError(ioe);
}
}
如您所见,客户端连接并发送请求。服务器读取该请求,然后写入客户端将读取的响应。
此代码的问题在于客户端中的OutputStream.close() 和服务器中的InputStream.close()。如 Javadocs 中所述,关闭流将关闭 Socket。结果是当客户端尝试读取服务器响应时,Socket 已经关闭。
我已经设法通过调用Socket.shutdownInput 和Socket.shutdownOutput 来克服这个问题。但是我仍在思考这是否是正确的做法
请注意,当服务器写入响应或客户端读取响应时,使用close() 关闭流不会产生问题(我猜想关闭在客户端和服务器之间是同步的)。
所以我的问题是:
- 使用 Socket 关闭方法是否正确?
- 我可以用
close()继续关闭最后一个流吗(发送和阅读时 来自服务器的响应) - 关闭时关闭是否会保留一些数据? 缓冲区并且不会被发送?
【问题讨论】:
-
将 socket.close() 放入 finally 块中。
-
@PeterLawrey 你的意思是不关闭流并关闭套接字吗?如果是的话,我想我应该关闭两端的套接字,对吧?
-
你应该关闭套接字,如果你想先刷新输出流,你可能想先关闭或刷新它。
-
@PeterLawrey 我很困惑。 Javadocs 清楚地表明(这段代码证明了这一点),当 Stream 关闭时,Socket 也关闭了。你的意思是像下面诺顿所说的:在 finally 块中关闭流然后关闭套接字?
-
如果你有一个 BufferedOuptutStream 并且它有未发送的数据(在缓冲区中)你只需要关闭流如果不是这种情况,你只需要关闭套接字。如果关闭套接字并且有未发送的数据,则永远不会发送。
标签: java android sockets inputstream