游走的bit 2022-12-06 19:50
浏览 14
已结题

Java Socket关闭时,如何避免RST包的出现?

我在windows环境测试了下面的代码:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.TimeUnit;

/**
 * @Author: wanglonglong
 * @Date: 2022/10/26
 * @TIME: 14:22
 */
public class TCPServer {
    public static void main(String[] args) throws IOException, InterruptedException {
        try(ServerSocket socketServer = new ServerSocket()) {
            socketServer.bind(new InetSocketAddress("0.0.0.0",8899),1);
            Socket client = socketServer.accept();
            System.out.println("client连接上来了");
            int i = -1;
            while((i=client.getInputStream().read())!=-1) {
                if(i==2)
                    client.shutdownOutput();
                System.out.println(i);
            }

            System.out.println("client关闭了");
            client.close();
            System.out.println("server close");
        }
    }
}

client端代码:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.concurrent.TimeUnit;

/**
 * @Author: wanglonglong
 * @Date: 2022/5/16
 * @TIME: 13:07
 */
public class Test6 {
    public static void main(String[] args) throws IOException, InterruptedException {
        Socket socket = new Socket();
        socket.bind(new InetSocketAddress(8080));
        socket.connect(new InetSocketAddress("localhost",8899));
        socket.getOutputStream().write(1);
//        TimeUnit.SECONDS.sleep(10);
        socket.getOutputStream().write(2);
        System.out.println("shutdown output");
        socket.shutdownOutput();
        while(socket.getInputStream().read()!=-1) {

        }
        System.out.println("shutdown");
        socket.close();

    }

}


理论上,TCP连接的释放应该走4次挥手的完整流程,但是实际上的效果如下:

img


上图的8080表示client,8899表示server,由client发起close请求,可以看到,在四次挥手的最后一次挥手过程(也就是client进入TIME_WAIT状态时,需要给server回复最后一个ACK的过程),server端已经关闭了,因此对于Client反馈的ACK包,直接返回了RST。

###我的问题
java的官方文档中明确说明,Socket默认的构造对象下,close()方法是使用四次挥手来进行的,而不是RST,而上面的server端代码,增加了下图的代码后就可以正常运行了

img

但这种方式并不优雅,我改如何修改我的代码,从而避免RST包的出现??

  • 写回答

0条回答 默认 最新

    报告相同问题?

    问题事件

    • 已结题 (查看结题原因) 12月6日
    • 创建了问题 12月6日

    悬赏问题

    • ¥15 C#中的编译平台的区别影响
    • ¥15 软件供应链安全是跟可靠性有关还是跟安全性有关?
    • ¥15 电脑蓝屏logfilessrtsrttrail问题
    • ¥20 关于wordpress建站遇到的问题!(语言-php)(相关搜索:云服务器)
    • ¥15 【求职】怎么找到一个周围人素质都很高不会欺负他人,并且未来月薪能够达到一万以上(技术岗)的工作?希望可以收到写有具体,可靠,已经实践过了的路径的回答?
    • ¥15 Java+vue部署版本反编译
    • ¥100 对反编译和ai熟悉的开发者。
    • ¥15 带序列特征的多输出预测模型
    • ¥15 Python 如何安装 distutils模块
    • ¥15 关于#网络#的问题:网络是从楼上引一根网线下来,接了2台傻瓜交换机,也更换了ip还是不行