背景

在上一讲网络编程-关闭连接-C/C++相关系统调用中,提到过,目前项目使用Netty框架来实现的网络编程,查看netty源码可以得知,netty最终是调用了java Nio的close接口做的关闭操作,那么想研究清楚这个close操作究竟做了什么,可以从两个方向入手,这两个方向也是从下至上的。

  1. 搞清楚如果使用C/C++编程,应该调用哪个系统调用函数?函数内部做了什么,涉及到什么TCP/IP的协议参数,这些已经在上一讲中研究明白了。
  2. 搞清楚java nio在调用close方法时,究竟使用了哪个系统调用?

这一讲,主要研究解决第二个问题,搞清楚java nio在调用close方法时,究竟使用了哪个系统调用?

实验

在实验中,我们会使用linux下的strace工具,来跟踪系统调用。

使用我们的测试代码,用netty框架搭建了一个客户端,其中通过web接口传入ip端口进行连接,连接成功以后,在channelActive回调方法中先调用一个写文件方法,然后关闭channel。

测试代码上传到github上:

部分关键代码如图:

@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
//写入本地文件测试字符,然后关闭channel
FileWriter fileWriter = new FileWriter("/root/test.txt");
fileWriter.write("test test hold on");
fileWriter.flush();
fileWriter.close(); //调用同步方法关闭
ChannelFuture sync = ctx.channel().close().sync();
if(sync.isSuccess()){
System.out.println("关闭成功!");
}else{
System.out.println("关闭失败!");
}
}

在linux虚拟机上,使用下面指令运行该程序

[root@localhost Downloads]# java -jar pro-test-demo-0.0.1-SNAPSHOT.jar

然后使用ps -ef | grep "java"得到该进程的pid。

[root@localhost Downloads]# ps -ef | grep "java"
root 3029 2940 31 13:48 pts/0 00:00:13 java -jar pro-test-demo-0.0.1-SNAPSHOT.jar
root 3136 3101 0 13:49 pts/2 00:00:00 grep --color=auto java

使用strace跟踪系统调用,命令如下:

strace -tt -T -f -v -e trace=all -p 3029 -o ouput.log

java程序运行起来如下,我们使用postman传递了ip和端口,看到日志输出为连接成功,并且输出关闭成功!

[root@localhost Downloads]# java -jar pro-test-demo-0.0.1-SNAPSHOT.jar 

  .   ____          _            __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.4.RELEASE) 2020-07-14 13:48:52.225 INFO 3029 --- [ main] c.n.icomp.protestdemo.jfdj.NettyClient : Starting NettyClient v0.0.1-SNAPSHOT on localhost.localdomain with PID 3029 (/root/Downloads/pro-test-demo-0.0.1-SNAPSHOT.jar started by root in /root/Downloads)
2020-07-14 13:48:52.229 INFO 3029 --- [ main] c.n.icomp.protestdemo.jfdj.NettyClient : No active profile set, falling back to default profiles: default
2020-07-14 13:48:53.608 INFO 3029 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
2020-07-14 13:48:53.618 INFO 3029 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data repositories in DEFAULT mode.
2020-07-14 13:48:53.694 INFO 3029 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 55ms. Found 0 repository interfaces.
2020-07-14 13:48:54.374 INFO 3029 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 9876 (http)
2020-07-14 13:48:54.410 INFO 3029 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-07-14 13:48:54.410 INFO 3029 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.17]
2020-07-14 13:48:54.504 INFO 3029 --- [ main] o.a.c.c.C.[.[localhost].[/protest] : Initializing Spring embedded WebApplicationContext
2020-07-14 13:48:54.504 INFO 3029 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2187 ms
2020-07-14 13:48:55.144 INFO 3029 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-07-14 13:48:55.434 INFO 3029 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 9876 (http) with context path '/protest'
2020-07-14 13:48:55.436 INFO 3029 --- [ main] c.n.icomp.protestdemo.jfdj.NettyClient : Started NettyClient in 3.968 seconds (JVM running for 4.79)
2020-07-14 13:50:10.685 INFO 3029 --- [nio-9876-exec-1] o.a.c.c.C.[.[localhost].[/protest] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-07-14 13:50:10.685 INFO 3029 --- [nio-9876-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2020-07-14 13:50:10.691 INFO 3029 --- [nio-9876-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 6 ms
接收到参数:{"ip":"10.43.11.240","port":"20108"}
连接成功!
关闭成功!

最后打开output.log查看系统调用

为了便于我搜索,我提前在代码中加入了关键的一行

fileWriter.write("test test hold on");

所以搜索的时候,可以先搜索test test hold on,找到对应写入的系统调用,附近应该就是close相关的系统调用了。

3494  13:53:04.722628 write(103, "test test hold on", 17) = 17 <0.000060>
3494 13:53:04.722755 close(103) = 0 <0.000251>
3494 13:53:04.723141 getsockopt(102, SOL_SOCKET, SO_LINGER, {l_onoff=0, l_linger=0}, [8]) = 0 <0.000080> 3499 13:53:17.206962 close(102) = 0 <0.000012>

可以发现,fd为102的socket就是我们需要检测的socket,在调用close真正关闭之前,还进行了获取SO_LINGER的系统调用getsockopt,并且l_onoff=0, l_linger=0,会关闭读写两方向连接,并且在后台继续发送发送缓冲区中的内容,后面调用close返回0,代表成功。

总结

JAVA nio的close操作,使用的是close系统调用。关于close系统调用,可以参考上一讲中的内容。网络编程-关闭连接-C/C++相关系统调用

网络编程-关闭连接(2)-Java的NIO在关闭socket时,究竟用了哪个系统调用函数?的更多相关文章

  1. 聊聊iOS中网络编程长连接的那些事

    1.长连接在iOS开发中的应用 常见的短连接应用场景:一般的App的网络请求都是基于Http1.0进行的,使用的是NSURLConnection.NSURLSession或者是AFNetworking ...

  2. 已看1.熟练的使用Java语言进行面向对象程序设计,有良好的编程习惯,熟悉常用的Java API,包括集合框架、多线程(并发编程)、I/O(NIO)、Socket、JDBC、XML、反射等。[泛型]\

    1.熟练的使用Java语言进行面向对象程序设计,有良好的编程习惯,熟悉常用的Java API,包括集合框架.多线程(并发编程).I/O(NIO).Socket.JDBC.XML.反射等.[泛型]\1* ...

  3. 网络编程1--毕向东java基础教程视频学习笔记

    目录: 01 网络编程概述1 02 网络编程概述2 03网络编程 网络模型 04网络编程 IP地址 05网络编程 TCP和UDP 06网络编程 Socket 07网络编程 UDP发送端 01 网络编程 ...

  4. 网络编程2--毕向东java基础教程视频学习笔记

    Day 23 08 Udp接收端09 Udp键盘录入数据方式10 Udp聊天11 TCP传输12 TCP传输213 TCP练习14 TCP复制文件 08 Udp接收端 需求:定义一个应用程序,用于接收 ...

  5. UNIX网络编程——TCP连接的建立和断开、滑动窗口

    一.TCP段格式: TCP的段格式如下图所示: 源端口号与目的端口号:源端口号和目的端口号,加上IP首部的源IP地址和目的IP地址唯一确定一个TCP连接. 序号:序号表示在这个报文段中的第一个数据字节 ...

  6. python网络编程--TCP连接的三次握手(三报文握手)与四次挥手

    一.TCP连接 运输连接有三个阶段: 连接建立.数据传送和连接释放. 在TCP连接建立过程中要解决以下三个问题: 1,要使每一方能够确知对方的存在. 2.要允许双方协商一些参数(如最大窗口之,是否使用 ...

  7. 找呀志_java网络编程(4)TCP/IP、Http和Socket差额

    经java网络编程(1)网络体系结构及通信协议我知道IP协议相应于网络层.TCP协议相应于传输层.而HTTP协议相应于应用层, 三者从本质上来说没有可比性 TPC/IP协议是传输层协议,主要解决数据怎 ...

  8. 网络编程学习笔记(二)基于TCP的Socket编程

    1.Socket:英文意思插座.两个Java应用程序可以通过一个双向的网络通信连接实现数据交换,这个双向链路的一端称为一个Socket. 2.Socket通常用来实现client-server(客户端 ...

  9. 网络编程3--毕向东java基础教程视频学习笔记

    Day24 01 TCP上传图片02 客户端并发上传图片03 客户端并发登录04 浏览器客户端-自定义服务端05 浏览器客户端-Tomcat服务端 01 TCP上传图片 import java.net ...

  10. 网络编程4--毕向东java基础教程视频学习笔记

    Day24 06 自定义浏览器-Tomcat服务端07 自定义图形界面浏览器-Tomcat服务端08 URL-URLConnection09 小知识点10 域名解析 06 自定义浏览器-Tomcat服 ...

随机推荐

  1. conda创建label标注环境

    conda create -n label python=3.6 conda activate label pip install labeimg -i https://pypi.tuna.tsing ...

  2. JMeter JSR223 Sampler 教程:性能测试的魔法棒

    JMeter JSR223 Sampler 教程:性能测试的魔法棒 宝子们,今天咱要深入探索 JMeter 里超厉害的 JSR223 Sampler,它就像是一把万能钥匙,能打开性能测试的各种奇妙大门 ...

  3. CDS标准视图:维修工单实际成本数据 I_MaintOrderActualCostDataCube

    视图名称:维修工单实际成本数据 I_MaintOrderActualCostDataCube 视图类型:基础 视图代码: 点击查看代码 @VDM.viewType: #COMPOSITE @AbapC ...

  4. CDS标准视图:设备 I_Equipment

    视图名称:I_Equipment 视图类型:基础视图 视图内容: 设备编码和设备内容 设备来源及详细信息 有效期 事务代码: IE03,IH08 视图代码 点击查看代码 @EndUserText.la ...

  5. React、Angular、Vue.js三者比较指南

    Vue-React-Angular三者区别   1. 基本概念Angular 是一个应用设计框架与开发平台,用于创建高效.复杂.精致的单页面应用. React 是一个用于构建用户界面的 JavaScr ...

  6. 测试 【子牙-writing】 大模型

    参考:姜子牙大模型系列 | 写作模型ziya-writing开源!开箱即用,快来认领专属你的写作小助手吧 封神榜:https://github.com/IDEA-CCNL/Fengshenbang-L ...

  7. 让AI碰撞!“天翼云息壤杯”高校AI大赛江苏赛区交流会热力开场!

    由中国电信集团有限公司主办,天翼云科技有限公司承办的"天翼云息壤杯"高校AI大赛正在火热进行中.为了提高江苏赛区学生的参赛热情,增强学生的创作能力,江苏电信.天翼云华东中心于12月 ...

  8. SQL注入的业务场景以及危害

    SQL注入的业务场景以及危害 在现代Web应用中,数据库是存储和检索数据的核心组件.然而,当Web应用未能正确验证和过滤用户输入时,就可能会遭受SQL注入攻击.SQL注入是一种严重的安全漏洞,它允许攻 ...

  9. [记录点滴]编译安装luarocks、luacheck、luautf8

    [记录点滴]编译安装luarocks.luacheck.luautf8 0x00 摘要 记录一次安装luarocks&第三方库的过程. 0x01 luarocks 如今每个语言体系中都有一个包 ...

  10. FLink自定义Source,不停生产数据

    一.代码模板 VideoOrder.java package net.xdclass.model; import java.util.Date; import lombok.AllArgsConstr ...