基于TCP的Socket编程

本文详细介绍了TCP Socket编程的过程,包括服务端与客户端的交互步骤,如bind、listen、accept和connect。讲解了listen参数backlog的意义,它表示已完成连接队列的长度。同时阐述了TCP连接关闭时的四次挥手过程,以及服务端如何通过read感知到客户端的关闭。此外,还解释了accept发生在三次握手成功之后。
摘要由CSDN通过智能技术生成

Socket是应用层与传输层的一个抽象,将复杂的TCP/IP协议隐藏在Socket接口之后,只对应用层暴露简单的接口。

1.针对TCP该如何Socket编程

在这里插入图片描述

  • 服务端和客户端初始化Socket,得到文件描述符
  • 服务端调用bind,将绑定IP地址和端口
  • 服务端调用listen,进行监听
  • 服务端调用accept,等待客户端连接
  • 客户端调用connect,向服务器端的地址和端口发送连接请求
  • 服务端accept返回用于传输的socket的文件描述符
  • 客户端调用write写入数据,服务端调用read读取数据
  • 客户端断开连接时,会调用close,那么服务端read读取数据的时候,就会读到了EOF,黛处理完数据后,服务端调用close,表示连接关闭

这里需要主要的是,服务端调用accept时,连接成功了会返回一个已经完成连接的socket,后续用来传输数据。
所以,监听的socket和真正用来传送数据的socket,是两个socket,一个叫做监听socket,一个叫做已完成连接socket。
成功连接建立之后,双方开始通过read和write函数来读写数据,就像一个文件流里面写东西一样。

2.listen时候参数backlog的意义

在这里插入图片描述
Linux内核中会维护两个队列:

  • 未完成连接队列(SYN队列):接收到一个SYN连接请求,处于SYN_RCVD状态
  • 已完成连接队列(Accept队列):已完成TCP三次握手过程,处于ESTABLISHED状态

int listen(int socketfd,int backlog)

  • 参数一socketfy为socketfd文件描述符
  • 参数二backlog,这个参数在历史版本有一定的变化

在早期的Linux内核backlog是SYN队列的大小
在Linux内核2.2之后,backlog变成accept队列,也就是已完成连接建立的队列长度,所以现在通常认为backlog是accept队列。

但是上限值是内核参数somaxconn的大小,也就是锁accept队列长度=min(backlog,somaxconn)

3.accept发送在三次握手的哪一步

在这里插入图片描述
客户端connect成功返回是在第二次握手,服务端accept成功返回是在三次握手成功之后。

4.客户端调用close了。连接时断开的流程是什么?

在这里插入图片描述

  • 客户端调用close,表面客户端没有数据需要发送了,则此时会向服务端发送FIN报文,进入FIN_WAIT1状态
  • 服务端接收到FIN报文,TCP协议栈会为FIN包插入一个文件结束符EOF到接收缓冲区中,应用程序可以通过read调用来感知这个FIN包。这个EOF会被放在已排队等候的其他已接收的数据之后,这就意味着服务端需要处理这种异常情况,因为EOF表示该连接上再无额外的数据到达。此时,服务端进入CLOSE_WAIT 状态。
  • 接着,当处理完数据后,自然会读到EOF,于是也调用close关闭它的套接字,这会使客户端会发出一个FIN包,之后处于LAST_ACK状态
  • 服务端收到ACK确认包后,就进入了最后的CLOSE状态
  • 客户端经过2MSL时间之后,也进入CLOSE状态
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值