19connection reset rst fin linger(一)
package com.jds.test.bio.p11; /** * * Created by joyce on 2019/11/26. */ import java.net.InetSocketAddress; import java.net.Socket; public class Client { public static final int PORT = 12123; public static final int BUFFER_SIZE = 1024; public static void main(String []f) throws Exception { new Client().client(); } //客户端代码 public void client() throws Exception{ final String s1 = "49.235.75.155";// tx final String s2 = "localhost"; byte[] buffer; Socket s = new Socket(); /** * 决定rst or fin */ // s.setSoLinger(true, 0); s.bind(new InetSocketAddress(8888)); s.connect(new InetSocketAddress(s1,PORT)); int i = s.getInputStream().read(buffer = new byte[BUFFER_SIZE]); System.out.println(new String(buffer,0,i)); /** * 程序自然结束,close */ } }
package com.jds.test.bio.p11; /** * * Created by joyce on 2019/11/26. */ import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class Server { public static final int PORT = 12123; public static final int BUFFER_SIZE = 1024; public static void main(String [] f) { try { new Server().server(f.length == 0 ? "1":f[0]); } catch (Exception e) { e.printStackTrace(); } } //服务端代码 public void server(String flag) throws IOException, InterruptedException{ System.out.println(flag); ServerSocket ss = new ServerSocket(PORT); while(true) { Socket s = ss.accept(); s.getOutputStream().write("hello ".getBytes()); s.getOutputStream().flush(); Thread.sleep(5000); // 没什么鸟用 System.out.println(s.isClosed()); if("2".equals(flag)) { s.getOutputStream().write(1); s.getOutputStream().flush(); } if("3".equals(flag)) { s.getOutputStream().write(1); s.getOutputStream().flush(); Thread.sleep(2000); s.getOutputStream().write(2); } while (s.getInputStream().read(new byte[BUFFER_SIZE]) != -1) { ; }; /** * 显示close,发出fin包 */ s.close(); } } }
(一)false read
[root@VM_0_9_centos ~]# java -jar netty-in-action-0.1-SNAPSHOT-jar-with-dependencies.jar
1
false
5s内
JoycedeMacBook:netty-test joyce$ netstat -an|grep 12123
tcp4 0 0 192.168.1.9.8888 49.235.75.155.12123 FIN_WAIT_2
5s后
JoycedeMacBook:netty-test joyce$ netstat -an|grep 12123
tcp4 0 0 192.168.1.9.8888 49.235.75.155.12123 TIME_WAIT
(二)true read
^C[root@VM_0_9_centos ~]# java -jar netty-in-action-0.1-SNAPSHOT-jar-with-dependencies.jar
1
false
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:210)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at java.net.SocketInputStream.read(SocketInputStream.java:127)
at com.jds.test.bio.p11.Server.server(Server.java:45)
at com.jds.test.bio.p11.Server.main(Server.java:18)
netstat 无
(三)false write 服务端入参2
[root@VM_0_9_centos ~]# java -jar netty-in-action-0.1-SNAPSHOT-jar-with-dependencies.jar 2
2
false
5s内
JoycedeMacBook:netty-test joyce$ netstat -an|grep 12123
tcp4 0 0 192.168.1.9.8888 49.235.75.155.12123 FIN_WAIT_2
5s后
JoycedeMacBook:netty-test joyce$ netstat -an|grep 12123
(四)true write 服务端入参2
^C[root@VM_0_9_centos ~]# java -jar netty-in-action-0.1-SNAPSHOT-jar-with-dependencies.jar 2
2
false
java.net.SocketException: Connection reset
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:115)
at java.net.SocketOutputStream.write(SocketOutputStream.java:134)
at com.jds.test.bio.p11.Server.server(Server.java:41)
at com.jds.test.bio.p11.Server.main(Server.java:18)
netstat 无
(五)false write write 服务端入参3
[root@VM_0_9_centos ~]# java -jar netty-in-action-0.1-SNAPSHOT-jar-with-dependencies.jar 3
3
false
java.net.SocketException: Broken pipe (Write failed)
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111)
at java.net.SocketOutputStream.write(SocketOutputStream.java:134)
at com.jds.test.bio.p11.Server.server(Server.java:49)
at com.jds.test.bio.p11.Server.main(Server.java:18)
JoycedeMacBook:netty-test joyce$ netstat -an|grep 12123
tcp4 0 0 192.168.1.9.8888 49.235.75.155.12123 FIN_WAIT_2
JoycedeMacBook:netty-test joyce$ netstat -an|grep 12123
A 本地 mac client
B centos 7 server
结论:
1 进程退出,tcp连接还在
2 A fin B, B read, no exception, fin_wait2(within 5s)->time_wait(after 5s)
3 A rst B, B read, Connection reset,netstat none(within and after 5s)
4 A fin B, B write, no exception, A rst B, fin_wait2(within 5s)->none(after 5s)
5 A rst B, B write, Connection reset, netstat none(within and after 5s)
6 A fin B, B write, no exception, A rst B, B write again, Broken Pipe, fin_wait2(within 5s)->none(after 5s)
7 rst后,netstat nothing,没有time_wait fin_wait,也无需ack
8 一三五情况中程序sleep,但是tcp内核发出应对fin的ack
9 socket.isClosed没用
引子:
第(三)种情况是典型的4次挥手,为什么会出现client拒绝处理server最后的那个包,直接发出RST,在下一节中我们讨论