记一次代码检视 Socket flush的问题
【摘要】 前言记一次代码检视中领悟到的知识,和大家一起交流 正文提交上来的代码大概是这个样子的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过多。
经过大家的讨论,主要的矛盾点在shutdownOutput
和flush
的顺序。首先想到的是 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并没有收到数据
还没运行26行的时候,数据就已经发送到python服务器了
总结
这个时候证明我们的推测是正确的,shutdownOutput
方法自带了flush
效果。
我也尝试了配置tcpNoDeplay
参数,配不配置tcpNoDelay,都是一样的效果。看起来jvm都有缓冲
那么已经调用了shutdownOutput
方法之后,flush
方法还有没有必要调用呢,从clean code
的角度,flush
方法的调用已经是没有任何必要的了,建议删除。一般场景下可能不会有问题,但是如果极端场景,比如在25行到26行之间,程序陷入了长gc,这行就有可能抛出IOException,影响原来的逻辑。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)