网络编程实战
盛延敏
前大众点评云平台首席架构师
44207 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 40 讲
网络编程实战
15
15
1.0x
00:00/00:00
登录|注册

04 | TCP三次握手:怎么使用套接字格式建立连接?

初始化IPv4 TCP 套接字的例子
通配地址
TCP三次握手的解读
connect: 拨打电话
accept: 电话铃响起了……
listen:接上电话线,一切准备就绪
bind: 设定电话号码
创建套接字
思考题
总结
著名的TCP三次握手
客户端发起连接的过程
服务端准备连接的过程
TCP三次握手

该思维导图由 AI 生成,仅供参考

你好,我是盛延敏,这里是网络编程实战第 4 讲,欢迎回来。
在上一讲里我们介绍了 IPv4、IPv6 以及本地套接字格式,这一讲我们来讲一讲怎么使用这些套接字格式完成连接的建立,当然,经典的 TCP 三次握手理论也会贯穿其中。我希望经过这一讲的讲解,你会牢牢记住 TCP 三次握手和客户端、服务器模型。
让我们先从服务器端开始。

服务端准备连接的过程

创建套接字

要创建一个可用的套接字,需要使用下面的函数:
int socket(int domain, int type, int protocol)
domain 就是指 PF_INET、PF_INET6 以及 PF_LOCAL 等,表示什么样的套接字。
type 可用的值是:
SOCK_STREAM: 表示的是字节流,对应 TCP;
SOCK_DGRAM: 表示的是数据报,对应 UDP;
SOCK_RAW: 表示的是原始套接字。
参数 protocol 原本是用来指定通信协议的,但现在基本废弃。因为协议已经通过前面两个参数指定完成。protocol 目前一般写成 0 即可。

bind: 设定电话号码

创建出来的套接字如果需要被别人使用,就需要调用 bind 函数把套接字和套接字地址绑定,就像去电信局登记我们的电话号码一样。
调用 bind 函数的方式如下:
bind(int fd, sockaddr * addr, socklen_t len)
我们需要注意到 bind 函数后面的第二个参数是通用地址格式sockaddr * addr。这里有一个地方值得注意,那就是虽然接收的是通用地址格式,实际上传入的参数可能是 IPv4、IPv6 或者本地套接字格式。bind 函数会根据 len 字段判断传入的参数 addr 该怎么解析,len 字段表示的就是传入的地址长度,它是一个可变值。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文详细介绍了TCP连接建立的关键过程,以及在服务器端和客户端之间如何使用套接字格式建立连接。在服务器端,通过创建套接字、绑定地址和端口、监听客户端连接请求,并通过accept函数接受连接,完成了连接的建立。而客户端则通过创建套接字并调用connect函数向服务器端发起连接请求。文章还解释了connect函数的构建和TCP三次握手的过程,帮助读者理解了TCP连接建立的基本原理和实现过程。此外,还提出了两道思考题,引发读者对非阻塞调用套接字和客户端调用bind函数的思考。整体而言,本文以清晰的语言和详细的示例,帮助读者快速了解TCP连接建立的过程和相关技术特点。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《网络编程实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(101)

  • 最新
  • 精选
  • 疾风知劲草
    之前看过一些文章解释,为什么tcp建立连接需要三次握手,解释如下 tcp连接的双方要确保各自的收发消息的能力都是正常的。 客户端第一次发送握手消息到服务端, 服务端接收到握手消息后把ack和自己的syn一同发送给客户端,这是第二次握手, 当客户端接收到服务端发送来的第二次握手消息后,客户端可以确认“服务端的收发能力OK,客户端的收发能力OK”,但是服务端只能确认“客户端的发送OK,服务端的接收OK”, 所以还需要第三次握手,客户端收到服务端的第二次握手消息后,发起第三次握手消息,服务端收到客户端发送的第三次握手消息后,就能够确定“服务端的发送OK,客户端的接收OK”, 至此,客户端和服务端都能够确认自己和对方的收发能力OK,,tcp连接建立完成。

    作者回复: 赞

    2019-08-09
    17
    208
  • 阿卡牛
    这个问题的本质是, 信道不可靠, 但是通信双发需要就某个问题达成一致. 而要解决这个问题, 无论你在消息中包含什么信息, 三次通信是理论上的最小值. 所以三次握手不是TCP本身的要求, 而是为了满足"在不可靠信道上可靠地传输信息"这一需求所导致的

    作者回复: 赞。

    2019-08-09
    4
    92
  • leesper
    思考题1:非阻塞调用的场景就是高性能服务器编程!我所有的调用都不需要等待对方准备好了再返回,而是立即返回,那么我怎么知道是否准备好了?就是把这些fd注册到类似select或者epoll这样的调用中,变多个fd阻塞为一个fd阻塞,只要有任何一个fd准备好了,select或者epoll都会返回,然后我们在从中取出准备好了的fd进行各种IO操作,从容自然 ^o^

    作者回复: 赞,下面的内容会讲到这部分了

    2019-08-19
    54
  • 鱼向北游
    关于三次握手 几句话解释清楚 1.信道不安全 保证通信需要一来一回 2.客户端的来回和服务端的来回 共四次 这是最多四次 3.客户端的回和服务端的来合并成一个,就是那个sync k ack j+1 4.这样就是三次握手

    作者回复: 很清楚,很简洁。

    2019-09-02
    49
  • eddy
    有个问题, 一次面试中遇到的, 客户端的第三次应答, 服务器没有收到, 然后客户端开始发消息给服务器, 这时候服务器和客户端的表现是什么? 客户端会收到什么返回?

    作者回复: 客户端发的消息是什么?如果三次应答服务器没有收到,服务器端连接没有建立,客户端误认为建立了,发送的报文应该会被设置为连接RST。

    2020-01-09
    5
    29
  • 学完这节,感觉TCP的三次握手机制,更明白了一些,相信此生都会记得,养成了翻评论的习惯,感觉有些同学的解释比老师的还要通俗易懂。 我的小结如下,假设只有客户端C和服务端S,两台机器: 1:啥是TCP的三次握手机制? TCP的三次握手机制,是C和S使用TCP协议进行通信,他们在正式建立链接前,先进行了三次简单的通信,只有这三次简单的同学成功了,才建立正式的连接,之所以说是简单的通信,因为这三次通信发送的消息比较简单,就是固定格式的同步报文和确认报文 2:TCP的三次握手机制的目的是啥? TCP协议的设计目标之一,就是保证通信信道的安全,而TCP的三次握手机制就是用于确认信道是否安全的手段之一,确认信道安全,最基本的首先要确认C和S都具备信息首发的能力吧!也就是C要确定S能收发信息,S要确定C能收发信息,咋确认呢?那就发送一条消息实验一下呗!所以,就有了TCP的三次握手机制,TCP的三次握手机制的核心目标就是要确认C和S之间的通信信道是安全的。 3:为啥是三次? 按道理来讲,C要确认S是否能够正确的收发消息,需要发生一条消息给S,然后接收到S的一条确认收到的消息才行,这一来一回就是两条消息。同理,S要确认C是否能够正确的收发消息,也需要这么玩。这样就需要两趟一来一回,总共需要四次通信,其实这么玩思维上一点负载都是没有的自然而然。 不过只是为了确认C和S能否正常通信的话,就如此设计,被聪明一看到就会骂傻X,人类孜孜不倦所追求是更快、更高、更强,计算机世界中这种追求更加的强烈,将S的确认收到C发送的消息和S能正常发生的消息一次性的都发给C岂不是更好,虽然增加了点消息的内容,但是相对于消息的传输消耗而言还是非常少的,而且从整体消耗上看,是减少了一次通信的过程,性能想必会更好。 很明显一次握手、两次握手都确认不了C和S的收发消息的能力是否OK。三次握手是比较简洁有效的方式,大于三次之上的握手机制也可以确认C和S是否能够正常通信,不过有些浪费资源了,毕竟三次就能搞定的事情,没必要搞三次至少,毕竟对于性能的追求我们是纳秒必争的。

    作者回复: 🐂。

    2019-11-20
    14
  • rongyefeng
    Linux内核2.2之后,socket backlog参数的形为改变了,现在它指等待accept的完全建立的套接字的队列长度,而不是不完全连接请求的数量。 不完全连接的长度可以使用/proc/sys/net/ipv4/tcp_max_syn_backlog设置。 老师,这里你讲的backlog是未完成连接的队列,是不是有误?

    作者回复: 我查看了一下资料,在Linux中backlog确实表示的是已完成(ESTABLISHED)且未accept的队列大小。而FreeBSD的实现是不同的,已经勘误修改。

    2020-05-14
    4
    11
  • dan
    "请问能听见吗""我能听见你的声音,你能听见我的声音吗" A先对B:你在么?我在的,我发一个消息看你能不能收到,我发J; B收到后,回答:我收到了你发的J,你的发送和我的接收功能正常,回你J+1;并且,我给你发个消息K,看我的发送和你的接收是否正常? A收到后,回答:我收到了你发的J+1和K,我回你K+1,告诉你的发送和我的接收正常; 通过前2次,表明:起点的发送和终点的接收,功能正常; 通过后2次,表明:终点的发送和起点的接收,功能正常; 由此保证:双方可以发送和接收对方的信息。

    作者回复: 解说的非常形象,点赞。

    2020-03-05
    8
  • Arthur.Li
    SYN:建立连接 FIN:关闭连接 ACK:响应 PSH:有DATA数据传输 RST:连接重置

    作者回复: 👍

    2020-04-02
    7
  • weeeee
    老师好,有一个问题想请教您一下 服务器端的连接进入ESTABLISHED 状态,课程上说的是accept返回后才进入,但是我自己实验发现只要客户端发送ack后,也就是第三次握手完成就进入了ESTABLISHED 状态,和accept没有关系,请问一下老师是我哪里理解错了吗?

    作者回复: 我的理解是accept之后会返回三次握手成功进入ESTABLISHED状态的连接,确实是先进入ESTABLISHED状态,然后从accept返回

    2019-08-13
    2
    7
收起评论
大纲
固定大纲
服务端准备连接的过程
创建套接字
bind: 设定电话号码
显示
设置
留言
99+
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部