看某神视频的时候,发现不用socket.shutdownOutput()服务端就会被阻塞,阻塞在如下代码块中:
后面想了下,其实在客户端代码中不调用socket.close()也会导致阻塞。
说回到客户端,如果不加如下代码就会阻塞。因为服务器会一直等待客户端的输出。既然服务器阻塞了,客户端等待着服务器的输出,也会被阻塞,所以导致客户端和服务端都被阻塞。
调用Socket.shutdownOutput()方法后,客户端输出的数据都将被发送,并加上 TCP 的正常连接终止序列(-1,也就是服务端终止循环的判断条件),这样服务端读取数据时就不会被阻塞了。
想必socket.close()也做了类似的事情。
但是本代码需要接收服务器的响应,所以不能关闭socket,只能单向关闭客户端输出流。
客户端代码如下:
public static void main(String[] args) {
try {
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9000);
OutputStream os = socket.getOutputStream();
FileInputStream fis = new FileInputStream(new File("D:\\2021\\ksnet\\src\\捕获.JPG"));
byte[] buffer = new byte[1024];
int len;
while((len = fis.read(buffer)) != -1) {
os.write(buffer,0,len);
}
//不加则会阻塞
socket.shutdownOutput();
//accept server message
InputStream inputStream = socket.getInputStream();
byte[] buffer2 = new byte[1024];
int len2;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while((len2 = inputStream.read(buffer2)) != -1) {
baos.write(buffer2);
}
System.out.println(baos.toString());
baos.close();
inputStream.close();
fis.close();
os.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
服务端代码如下:
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(9000);
Socket accept = serverSocket.accept();
InputStream inputStream = accept.getInputStream();
byte[] buffer = new byte[1024];
int len;
FileOutputStream fos = new FileOutputStream(new File("D:\\2021\\ksnet\\src\\receive.JPG"));
while((len = inputStream.read(buffer)) != -1) {
fos.write(buffer,0,len);
}
//notify client
OutputStream outputStream = accept.getOutputStream();
outputStream.write("服务器收到了".getBytes());
outputStream.close();
fos.close();
accept.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
版权声明:本文为u011403239原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。