TCP连接的部分细节及边界情况分析

这里写图片描述
图中即一个简单的socket建立连接的过程, 可以看到服务器端需要执行4个系统调用来准备好接收客户端的socket连接,而客户端在建立socket完成后,即可调用connect去主动连接服务器。

关于5个系统调用的具体含义详情可以去看unp,这里不多赘述,不过在一开始学习socket的时候我就对此处抱有疑问(也是没有细心看书导致),这里对我的疑问做一个解答。

Q:关于服务器与客户端的流程比较,为什么服务器端在调用socket创建完成一个套接字后,还需要去调用bind()、listen()、accept()这些系统调用,而客户端却在调用socket完成后直接调用connect进行连接?
A:这里的不理解主要是因为没去了解这些系统调用背后到底做了什么,而只是从字面理解。

  • bind
    bind为建立的socket指明了端口及ip地址,当客户端没有经过bind直接connect连接时,我们通过调用netstat命令可以看到它的端口号是由内核分配的,这对于TCP客户端来说没有任何问题,但是对于服务器端来说,如果端口号随机分配,那么客户们如何知道服务器的端口号是多少,另外当服务器重启,无法保证端口号跟原来一样,于是我们需要分配一个众所周知的端口号,以形成一个约定。
    另外bind在指定端口的同时还指定了IP地址,这是为了限制连接的客户,使得服务器只对部分指定的IP地址客户开放。

  • listen
    当一个套接字被建立时,它被假设为一个主动套接字,即它是一个将会调用connect进行连接的套接字,而listen将这样一个主动套接字转换成一个被动套接字。
    另外listen会使得内核为转换而来的被动监听套接字维护两个队列:未完成连接队列、已完成连接队列。当一个客户执行connect后进行三次握手,第一个SYN分节到达服务器后,就会在 未完成连接队列中 中建立一项(即套接字),处于SYN_RCVD状态。当三次握手完成时,内核将之前建立的项转移到已完成连接队列中。

  • accept
    用于从已完成连接队列队头返回下一个已完成连接,如果已完成连接队列为空,那么进程被投入睡眠。结合之前listen的解释,这里的accept就很容易理解了,它的作用只是在已经建立的连接队列中找到最早的一个

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值