1.握手

说明:

  下面涉及 FIN,SYN,ACK之类数据时,都是由TCP服务收发,

  涉及 accept, listen 之类api,都是 应用进程 完成。

  都统一使用 客户端,服务端描述,请自行分辨。

(1)首先描述下3次握手,TCP协议做了什么。

客户端,主动打开,发送自己的序列号SYNj,并期待对方回复ACKj+1

服务端,被动打开,接送自己的序列号SYNk和ACKj+1,并期待对方回复ACKk+1

客户端,接收对方ACK,己方打开完成,接收对方SYN,发送ACKk+1

服务端,接收对方ACK,己方打开完成。

分析下:

  首先打开分为,被动打开和主动打开。

  当接收到对方的ACK,则己方打开完成,则可以使用socket进行读写操作,但并不保证正常。

(2)结合 系统调用分析三次握手

客户端,listen,进行被动打开

服务端,connect ,进行主动打开,发送SYNj(如果乙方此时没有listen 完成,则connect 失败)

客户端,回复SYNk + ACKj+1, 应用层无任何变化。

服务端,收到 ACKj+1 + SYNk,并回复 ACKk+1, 甲方打开完成,connect 返回。

客户端,收到ACKj+1,可以进行 read,write。

服务端,accept,如果乙方没有收到 SYNj 则会阻塞,否则返回

服务端,收到ACKk+1,可以进行 read, write

总结下:

  从应用层角度,三次握手的开始,

    主动方,始于 connect,结束于 connect

    被动方,始于 listen ,结束于 listen

  accept 是被动方处理已经完成握手的主动方。

(3)实验

client

if  (0 > (connect(fd, (struct sockaddr *)&addr, sizeof(addr)))) {
perror("connect");
exit(-1);
} printf("success to connect\n"); write(fd, "hello world", strlen("hello world")); printf("write over\n"); close(fd);

server

        if (0 > listen(fd, 10)) {
perror("listen");
exit(-1);
} #if 1
printf("sleep for delay accept...\n");
sleep(5);
printf("sleep over\n");
#endif if (0 > (c_fd = accept(fd, (struct sockaddr *)&c_addr, &len))) {
perror("accept");
exit(-1);
} printf("success to accept\n"); while ((nbytes = read(c_fd, msg, MAX_READ))) {
msg[nbytes] = 0;
printf("%s", msg);
}
printf("\n"); if (0 > (nbytes = write(c_fd, "bye", 3))) {
perror("write");
exit(-1);
} printf("i have see bye\n"); close(fd);
close(c_fd);

实验结果

sleep for delay accept...
sleep over // 这里客户端已经通信结束,程序退出
success to accept
hello world
i have see bye

可以发现,客户端虽然已经挥手,但是服务端仍然视为握手完成,并正常的进行通信。

用netstat查看

可以发现,客户端进程虽然死掉,但打开的TCP服务并没有关闭,他在等待四次挥手完成。

因此服务端,虽然延迟处理,却依旧能正常处理通信。、

2.四次挥手

客户端,主动关闭,close,发送 FINm

服务端,被动关闭,接收FINm,发送ACKm+1

一段时间后,服务端,调用close,发送FINn

客户端,接收FINn,发送ACKn+1

总结下:

  当服务端接收到FIN时,注意,所有的TCP数据都由TCP服务处理,服务端的TCP收到FIN,并向服务端进程发送文件结束符EOF。

  EOF按照顺序在通信数据后面。

  当服务端进程read获得EOF,适时主动调用close,以发送 FINn。

  

  在客户端close,服务端没有close的阶段,称为 半关闭。

  这时,服务端进程可以发送数据,数据会交给客户端TCP服务,但不会上交给应用层。所以客户端进程是否存在,没关系。

最新文章

  1. NLP--十项沟通前的思想准备
  2. 使用 WinAppDeployCmd 部署Win10 App 到移动设备
  3. JQuery 实现页面无刷新
  4. ecshop新增一个编辑器
  5. BestCoder11(Div2) 1003 Boring count (hdu 5056) 解题报告
  6. [流媒体]live555简介(转)
  7. 解决问题之,wp项目中使用MatchCollection正则表达式匹配出错
  8. 201521123121 《Java程序设计》第1周学习总结
  9. OOP编程特性综合项目
  10. arcEngine开发之activeView.PartialRefresh(译)
  11. segmenter_worker.go
  12. php禁用函数设置及查看方法详解
  13. JAVA的运算符和条件结构
  14. C# .Net List<T>中Remove()、RemoveAt()、RemoveRange()、RemoveAll()的区别,List<T>删除汇总
  15. NET Core小细节杂记
  16. apply方法和call方法。函数属性与方法。
  17. day_5.27python网络编程
  18. 使用Java语言递归删除目录下面产生的临时文件
  19. 虚拟机安装VBoxAdditions增强功能
  20. MySQL数据库----存储过程

热门文章

  1. sop服务治理
  2. 【C语言程序设计】—最近超火的小游戏—【数字炸弹】!
  3. 【UR #12】实验室外的攻防战
  4. 解决python的requests库在使用过代理后出现拒绝连接的问题
  5. nginx安全:修改对外的服务软件名称并隐藏版本号(nginx1.18.0)
  6. sql中的Bulk 导入txt文本
  7. Pytest学习(二) - 断言的使用
  8. 微信小程序UI自动化:实践之后的记录01-选择工具/框架
  9. react-native 常见问题
  10. D. Serval and Rooted Tree (樹狀DP)