public class BIOServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(4396);
while (true) {
Socket socket = serverSocket.accept();
System.out.println("socket = " + socket);
new Thread(() -> {
try {
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
out.write("hello! I get your message that is follow".getBytes(Charset.forName("UTF-8")));
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) != -1) {
System.out.print(new String(buf, 0, len, Charset.forName("UTF-8")));
out.write(buf, 0, len);
}
out.write("\n end \n".getBytes(Charset.forName("UTF-8")));
out.flush();
socket.shutdownInput();
System.out.println("server close is");
Thread.sleep(5000);
System.out.println("server close os");
socket.shutdownOutput();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
}
public class BIOClient {
public static void main(String[] args) throws IOException, InterruptedException {
Socket socket = new Socket("127.0.0.1", 4396);
InputStream in = socket.getInputStream();
new Thread(() -> {
BufferedInputStream bufferIn = new BufferedInputStream(in);
byte[] buf = new byte[1024];
try {
int len;
while ((len = bufferIn.read(buf)) != -1) {
System.out.print(new String(buf, 0, len, Charset.forName("UTF-8")));
}
}catch (Exception e) {
e.printStackTrace();
}
try {
socket.shutdownInput();
System.out.println("client close is");
} catch (IOException e) {
e.printStackTrace();
}
}).start();
OutputStream out = socket.getOutputStream();
int cout = 10;
while (cout-- > 0) {
out.write(("this time is " + System.currentTimeMillis() + "\n").getBytes("UTF-8"));
}
Thread.sleep(5000);
System.out.println("client close os");
socket.shutdownOutput();
}
}
实验发现connection经历以下状态
经过试验发现java socket 中的 close 原理为主动发起一方 发送 FIN 被动方会自动发送ACK,但只有自己调用了close才会发送FIN 然后对面会自动发送ACK 成功关闭 TCP连接
对shutdowninput 和 output 只有shutdownoutput时候主动方才会发送FIN,对端自动发送ACK。只有对端自己调用shutdownoutput时才会发送FIN,此时的原主动方会自动发送ACK。 成功关闭TCP连接。
shutdowninput 只有关闭缓冲区的作用
|