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 原本是用来指定通信协议的,但现在基本废弃。因为协议已经通过前面两个参数指定完成。protocol 目前一般写成 0 即可。
bind: 设定电话号码

为了让别人使用,绑定号码

bind(int fd, sockaddr * addr, socklen_t len)
  • sockaddr * addr,通用地址格式
  • len 字段表示的就是传入的地址长度,它是一个可变值。

INADDR_ANY 来完成通配地址的设置(编写应用程序时并不清楚自己的应用程序将会被部署到哪台机器上)

listen:接上电话线,一切准备就绪

服务器处于可接听的状态,

int listen (int socketfd, int backlog)
  • socketfd 为套接字描述符,
  • 第二个参数 backlog,未完成连接队列的大小,这个参数的大小决定了可以接收的并发数目
accept: 电话铃响起了……
int accept(int listensockfd, struct sockaddr *cliaddr, socklen_t *addrlen)
  • listensockfd,通过 bind,listen 一系列操作而得到的套接字
  • cliadd 是通过指针方式获取的客户端的地址,addrlen 告诉我们地址的大小

客户端发起连接的过程

connect: 拨打电话
int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen)
  • servaddr 和 addrlen 分别代表指向套接字地址结构的指针和该结构的大小
  • 套接字的地址结构必须包含服务器ip地址和端口号
  • 客户在调用函数 connect 前不必非得调用 bind 函数,内核会确定源 IP 地址,按照算法选择一个临时端口作为源端口。
tcp调用connect函数三次握手报错的几种情况:
  • 1.无法建立,客户端发送SYN包没有任何响应,返回TIMEOUT错误,错误原因是对应的服务端IP写错
  • 2.客户端收到RST回答,客户端返回CONNECTION REFUSED错误,原因是客户端发送链接请求端口写错,因为RST是TCP发送错误时发送的一种TCP分节,
    产生RST的三个条件:
    1).目的某端口是SYN到达,然而该端口上没有正在监听的服务器
    2).TCP想取消一个已有连接
    3).TCP接受到一个根本不存在的连接的分支
  • 3.客户端发出的SYN包在网络引起“destination unreachable“(目的不可达错误),原因是双方路由不通。
    在这里插入图片描述
    这个模型都阻塞式:调用发起后不会直接返回,由操作系统内核处理之后才返回。
3次握手解读:

服务端通过socket,bind和listen完成被动套接字准备工作,被动等人连接,然后调用accept,就会阻塞到这里,等待客户端的连接来临;客户端通过调用socket和connect函数之后,也会阻塞。接下来是操作系统内核完成网络协议栈工作。

  1. c向s发送SYN包,告诉s当前发送序列号j,c进入SYNC_SENT状态
  2. s协议栈收到这个包之后,和c进行ack应答,应答值为j+1,表示SYN包j的确定,同时s发送一个SYN包,告诉c序列号为k,服务端进去SYNC_RCVD状态。
  3. c收到ACK之后,使应用程序从connect调用返回,表示c到s单向连接建立成功,c状态为ESTABLISHED,同时c也会对s的SYN包进行应答,应答数据为k + 1;
  4. 应答包到达s后,s使得accept阻塞调用返回,此时s到c单向连接也建立成功,s也进入established状态。

tcp连接的双方要确保各自的收发消息的能力都是正常的。
客户端第一次发送握手消息到服务端,
服务端接收到握手消息后把ack和自己的syn一同发送给客户端,这是第二次握手,
当客户端接收到服务端发送来的第二次握手消息后,客户端可以确认“服务端的收发能力OK,客户端的收发能力OK”,但是服务端只能确认“客户端的发送OK,服务端的接收OK”,
所以还需要第三次握手,客户端收到服务端的第二次握手消息后,发起第三次握手消息,服务端收到客户端发送的第三次握手消息后,就能够确定“服务端的发送OK,客户端的接收OK”,
至此,客户端和服务端都能够确认自己和对方的收发能力OK,,tcp连接建立完成。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值