记一次代码检视 Socket flush的问题

举报
张俭 发表于 2023/12/29 17:40:59 2023/12/29
【摘要】 前言记一次代码检视中领悟到的知识,和大家一起交流 正文提交上来的代码大概是这个样子的Socket socket = new Socket(ip, port);final DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());dataOutputStream.write("Hell...

前言

记一次代码检视中领悟到的知识,和大家一起交流

正文

提交上来的代码大概是这个样子的

Socket socket = new Socket(ip, port);
final DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataOutputStream.write("HelloWorld".getBytes(StandardCharsets.UTF_8));
socket.shutdownOutput();
dataOutputStream.flush();

这次主要是添加shutdownOutput的调用,及时关闭tcp会话,防止TW过多。

经过大家的讨论,主要的矛盾点在shutdownOutputflush的顺序。首先想到的是 flush方法放在了output后面,这样还能起作用吗?但是提交代码之前是经过测试的,这样子是可以正常工作的。然后的想法就是,傻逼了,想错了,shutdown应该自带flush效果,os都发fin了,之前的buffer肯定出去了。

我做个实验,来探究下是不是这样子的,我从python开启了一个http server来开启实验

python3 -m http.server

java测试类代码

package com.github.shoothzj.demo.basic;

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.io.DataOutputStream;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

/**
 * @author hezhangjian
 */
@Slf4j
public class DemoSocketSend {

    String ip = "127.0.0.1";

    int port = 8000;

    @Test
    public void testSocketSend() throws Exception {
        Socket socket = new Socket(ip, port);
        final DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
        dataOutputStream.write("HelloWorld".getBytes(StandardCharsets.UTF_8));
        socket.shutdownOutput();
        dataOutputStream.flush();
    }

}

随后我在25行和26行打了断点

当运行到25行的时候,python server并没有收到数据

image.png

还没运行26行的时候,数据就已经发送到python服务器了

image.png

总结

这个时候证明我们的推测是正确的,shutdownOutput方法自带了flush效果。
我也尝试了配置tcpNoDeplay参数,配不配置tcpNoDelay,都是一样的效果。看起来jvm都有缓冲
那么已经调用了shutdownOutput方法之后,flush方法还有没有必要调用呢,从clean code的角度,flush方法的调用已经是没有任何必要的了,建议删除。一般场景下可能不会有问题,但是如果极端场景,比如在25行到26行之间,程序陷入了长gc,这行就有可能抛出IOException,影响原来的逻辑。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。