JDK的SocketInputStream/SocketOutputStream的close方法
private boolean closing = false;
public void close() throws IOException {
// Prevent recursion. See BugId 4484411
if (closing)
return;
closing = true;
if (socket != null) {
if (!socket.isClosed())
socket.close();
} else
impl.close();
closing = false;
}
只要关闭Socket的InputStream或OutputStream其中任何一个,就关闭了Socket,这是不好的关闭方法。正确的方法应该是ShutdownInput/ShutdownOutput。
通常应用程序也可以在OutputStream写一个专门的结束标记替代EOF,然后flush。但在一些专门的编码的Stream里flush和close是有不同语意的,比如chunked编码、比如ZIP压缩等。在这种情况下调用了OutputStream的close就不能再接收任何信息。
比如使用ZIP压缩发送和接收数据的例子:
发送方:在Socket的OutputStream上封装GZIPOutputStream或DeflaterOutputStream
1、发送数据
2、发送数据结束标志(此时需要关闭GZIPOutputStream或DeflaterOutputStream,否则不保证全部数据都被发送至对方)
3、接收应答
4、结束
接收方:在Socket的InputStream上封装GZIPInputStream或InflaterInputStream
1、接收数据
2、收到数据结束标志
3、发送数据处理结果
4、结束。
按道理,发送方在发送完结束标志后应该可以关闭Output了,如果简单的调用了OutputStream.close,JDK的实现就会把InputStream和Socket同时关闭,这显然是不行的。为了正确的实现应用逻辑,就需要做一些额外的、本来不必要的处理。比如需要覆盖SocketOutputStream的close,让它调用Socket.ShutdownOutput,而不调用它的close.
分享到:
相关推荐
OutputStream outputStream = socket.getOutputStream(); outputStream.write(message.getBytes()); // 发送报文 InputStream inputStream = socket.getInputStream(); byte[] buffer = new byte[1024]; int ...
当有客户端连接时,`accept()`方法会返回一个新的Socket对象,表示这个特定的连接。例如: ```java ServerSocket serverSocket = new ServerSocket(8080); // 监听8080端口 Socket clientSocket = serverSocket....
5. **关闭连接**:完成数据传输后,记得关闭所有打开的Socket和InputStream/OutputStream,以释放系统资源: ```java in.close(); out.close(); clientSocket.close(); forwardSocket.close(); serverSocket....
在Java中,可以使用`Socket.close()`和`InputStream/OutputStream.close()`方法来关闭。 SocketTest示例可能包含了创建简单的客户端和服务器程序,演示了如何进行基本的数据交互,例如发送字符串或者文件。理解...
通常使用`Socket.close()`和`InputStream.close()`等方法。 6. **多线程** - 服务器端可能需要处理多个并发的客户端连接,因此可能需要用到多线程。每个连接的处理通常在一个独立的线程中完成,以确保服务器能同时...
OutputStream out = socket.getOutputStream(); InputStream in = socket.getInputStream(); // 读写数据 out.close(); in.close(); socket.close(); ``` 通过以上分析,我们可以看出在Android上实现Socket...
OutputStream outputStream = socket.getOutputStream(); DataOutputStream dataOutputStream = new DataOutputStream(outputStream); // 发送数据 dataOutputStream.writeUTF("客户端发送的数据"); // ...
在客户端和服务器端的通信过程中,要确保正确关闭资源,如Socket、InputStream和OutputStream,以避免内存泄漏。例如,在完成通信后,可以使用`finally`块关闭它们: ```java try { // 通信操作... } finally { ...
- **输出流(OutputStream)**:Socket对象也有`getOutputStream()`方法,返回一个OutputStream对象,用于向网络写入数据。 6. **网络通信流程**: - **客户端**:创建Socket对象,通过`Socket(String host, int ...
在客户端,使用 Socket 类来建立连接,并使用 InputStream 和 OutputStream 来读写数据。在服务器端,使用 ServerSocket 类来监听客户端的连接,并使用 Socket 对象来处理客户端的请求。 二、Java Socket 编程的...
OutputStream outputStream = socket.getOutputStream(); outputStream.write("发送的数据".getBytes()); InputStream inputStream = socket.getInputStream(); byte[] buffer = new byte[1024]; int length = ...
常见的子类有FileInputStream/FOutputStream用于文件操作,SocketInputStream/SocketOutputStream用于网络通信。 - **字符流**:Reader(输入)和Writer(输出)是所有字符流的基类。常见的子类有FileReader/...
### J2ME中使用Socket开发联网程序 #### 一、引言 在Java 2 Platform Micro Edition (J2ME) 的环境下,网络编程是实现移动设备间数据交换的关键技术之一。J2ME 提供了多种网络连接的方式,包括但不限于 HTTP、FTP...
这通常涉及调用Socket的close()方法,以及关闭InputStream和OutputStream。 总的来说,SocketDemo是一个学习和实践网络编程的好起点。它展示了如何使用Java的Socket类建立和维护网络连接,以及如何通过这些连接进行...
- **InputStream/OutputStream**:用于读取和写入数据流。 #### 三、服务端实现 接下来,我们将详细分析服务端的实现过程。 ##### 3.1 代码解析 服务端的主要逻辑体现在`Jserver1.java`文件中。下面是关键代码...
在处理完客户端的请求后,通常需要关闭`Socket`和`InputStream/OutputStream`以释放资源: ```java in.close(); out.close(); clientSocket.close(); ``` 注意,TCP是面向连接的,因此在服务器和客户端之间存在三...
- 通过Socket的InputStream和OutputStream读写数据。 - 关闭Socket和ServerSocket。 - 创建客户端: - 创建Socket,指定服务器的IP地址和端口号。 - 获取Socket的InputStream和OutputStream。 - 发送数据到...
以上代码展示了基本的Socket通信流程,但实际应用中还需要处理异常、多线程、数据编码解码等问题。例如,为了同时处理多个客户端连接,服务器端可能需要在一个单独的线程中处理每个连接,或者使用`java.nio`的非阻塞...
使用 `close()` 方法关闭 Socket 和流。 ### 8. 真机兼容性问题 虽然 J2ME Socket 编程提供了一种标准的通信方式,但不同设备的实现可能存在差异,且部分旧设备可能不完全支持某些特性。在实际应用中,需注意测试...
Java Socket API提供了一对`InputStream`和`OutputStream`接口,允许开发者以字节流的形式发送和接收数据。 在实际应用中,客户端和服务器通常会使用这些输入/输出流进行更复杂的交互,例如通过`DataInputStream`和...