先说结论:会。根据资料可以知道,Java的socket是一个全双工套接字,任何的输入流或输出流的close()都会造成socket关闭。
客户端:
package com.wyz.client;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
public class client{
public static void main(String[] args) throws IOException {
Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
OutputStream outputStream = socket.getOutputStream();
outputStream.write("hello,server".getBytes());
// 这里不能提前outputStream.close();
socket.shutdownOutput();
InputStream inputStream = socket.getInputStream();
byte[] buff = new byte[1024];
int readLen = 0;
while((readLen = inputStream.read(buff)) != -1){
System.out.println(new String(buff,0, readLen));
}
outputStream.close();
socket.close();
inputStream.close();
}
}
服务端:
package com.wyz.client;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class server {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("server等待连接...");
Socket socket = serverSocket.accept();
InputStream inputStream = socket.getInputStream();
byte[] buff = new byte[1024];
int readLen = 0;
while((readLen = inputStream.read(buff)) != -1){
System.out.println(new String(buff, 0 , readLen));
}
// 这里不能提前inputStream.close();
OutputStream outputStream = socket.getOutputStream();
outputStream.write("hello,client".getBytes());
inputStream.close();
outputStream.close();
socket.close();
serverSocket.close();
}
}
既然这样,那可以不单独进行socket.close()吗?
直接上源码:
// from SocketInputStream.java
public void close() throws IOException {
if (closing)
return;
closing = true;
if (socket != null) {
if (!socket.isClosed())
socket.close();
} else
impl.close();
closing = false;
}
// from Socket.java
public synchronized void close() throws IOException {
synchronized(closeLock) {
if (isClosed()) //如果输入/输出流关闭了,这里会直接返回
return;
if (created)
impl.close();
closed = true;
}
}
结论:当创建一个输入流或输出流时,这个流会持有对底层资源Socket的引用。当关闭这个输入流或输出流时,Java会自动关闭底层的资源,以确保资源被正确释放,避免资源泄漏和占用。
因此,在关闭输入流或输出流时,底层的Socket连接也会被关闭。所以不需要单独关闭Socket连接,只需关闭与之关联的输入流或输出流即可。这种设计简化了代码,同时也确保了资源的正确释放。这是Java I/O流的设计和实现机制。