TCP 和 UPD的差异:
TCP 是面向连接的,UDP 是面向无连接的。
TCP 提供可靠交付,无差错、不丢失、不重复、并且按序到达;UDP 不提供可靠交付,不保证不丢失,不保证按顺序到达。
TCP 是面向字节流的,发送时发的是一个流,没头没尾;UDP 是面向数据报的,一个一个地发送。
TCP 是可以提供流量控制和拥塞控制的,既防止对端被压垮,也防止网络被压垮。
-
连接:之所以叫建立连接是因为在客户端和服务端建立一定的数据结构来维护双方交互的状态来维护连接。
-
可靠:也是两端的数据结构做的事情。不丢失其实是数据结构在“点名”,顺序到达其实是数据结构在“排序”,面向数据流其实是数据结构将零散的包,按照顺序捏成一个流发给应用层。
-
socket 操作函数
int socket(int domain, int type, int protocol);
- domain:表示使用什么 IP 层协议。AF_INET 表示 IPv4,AF_INET6 表示 IPv6。
- type:表示 socket 类型。SOCK_STREAM,顾名思义就是 TCP 面向流的,SOCK_DGRAM 就是 UDP 面向数据报的,SOCK_RAW 可以直接操作 IP 层,或者非 TCP 和 UDP 的协议。例如 ICMP。
- protocol 表示的协议,包括 IPPROTO_TCP、IPPTOTO_UDP。
-
TCP 建立连接流程
image.png
- bind:
bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
TCP 的服务端要先监听一个端口,一般是先调用 bind 函数,给这个 socket 赋予一个端口和 IP 地址。服务端所在的服务器可能有多个网卡、多个地址,可以选择监听在一个地址,也可以监听 0.0.0.0 表示所有的地址都监听。 - linsten:进入 LISTEN 状态,等待客户端进行连接
三次握手
image.png
- accept:如果没有一个连接完成了三次握手,accept 就一直等待;如果有多个客户端发起连接,并且在内核里面完成了多个三次握手,建立了多个连接,这些连接会被放在一个队列里面。accept 会从队列里面取出一个来进行处理。如果想进一步处理其他连接,需要调用多次 accept,所以 accept 往往在一个循环里面。
们先在参数中指明要连接的 IP 地址和端口号,然后发起三次握手。内核会给客户端分配一个临时的端口。一旦握手成功,服务端的 accept 就会返回另一个 socket,这里需要注意的是,监听的 socket 和真正用来传送数据的 socket,是两个 socket,一个叫作监听 socket,一个叫作已连接 socket。成功连接建立之后,双方开始通过 read 和 write 函数来读写数据,就像往一个文件流里面写东西一样。
- UDP 流程
image.png
网友评论