目录
TCP(传输控制协议)和UDP(用户数据报协议)都是传输层的协议。
一、TCP
1、TCP头部结构
2、TCP传输的过程(协议分层)
3、编程流程
4、TCP编程接口函数:
int bind(int listenfd, struct sockaddr*addr, int addrlen);
int listen(int listenfd, size_t size);
int accept(int listenfd, struct sockaddr*cliaddr, int *len);
int recv(int linkfd, void *buff, size_t size, int flag);
int send(int linkfd, void *buff,size_t size, int flag);
int close(int fd);
int connent(int sockfd, struct sockaddr*seraddr, int serlen);
5、TCP的三次握手和四次挥手
(1)三次握手:
第一次:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;
第二次:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此 时服务器进入SYN_RECV状态;
第三次:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1)(连接成功)此包发送完毕,客户端和服务 器进入ESTABLISHED(TCP连接成功)状态,完成三次握手
(2)四次挥手:
第一次挥手:主动关闭方(客户端)发送一个FIN,用来关闭数据传送(由主动方到被动关闭方的数据传送),告诉被动关闭 方,我已经不会给你发送数据了,但主动方依然可以接受数据。(在FIN包之前发送出去的数据如果没有收到 对应的ACK确认报文,主动方依然会重发这些数据)
第二次挥手:被动关闭方(服务器)收到FIN包后,发送一个ACK(确认包)给对方,确认序号为收到序号+1;
第三次挥手:被动关闭方(服务器)发送一个FIN,用来关闭数据传送(被动关闭方到主动关闭方的数据传送),也就是告 诉主动关闭方:我数据已经发送完,不会再给你发送数据;
第四次挥手:主动关闭方(客户端)接收到FIN后,发送一个ACK给被动关闭方,确认序列号+1,;
6、画出三次握手和四次挥手的过程
7、为什么三次握手而不可以是一次握手或者两次握手?
不是一次握手的原因:TCP是面向连接,一次握手建立不了连接
不是两次握手的原因:防止已经失效的连接请求又发送到服务端,从而产生错误;
假定出现一种异常情况,客户端第一次发送出去的SYN报文段并没有丢失,而是在某个网络连接点滞留了,导致很长时间后才到达服务端,但服务端以为客户端请求了一个新的建立连接,但此时的SYN报文段已经失效了,客户端并没有重新发起建立连接,从而导致浪费了服务端的资源;
8、为什么连接的时候是三次握手,关闭的时候却是四次挥手?
因为当服务端收到客户端的SYN连接请求后,可以直接发送SYN+ACK报文用来同步和应答,但关闭连接时,当服务器收到FIN报文时不一定会立即关闭,所以只能先回复已收到关闭信息,但服务器还可以发送数据,客户端还可以收数据,只有等服务器数据发送完才可以发送FIN报文,所以需要四步挥手;
(四次挥手可以三次挥手但要保证服务端没有要发送的数据可以发送FIN包)
二、UDP
1、UDP的报头结构
2、编程流程
3、UDP编程接口函数
int bind(int listenfd, struct sockaddr*addr, int addrlen);
int recvfrom(int sockfd, void *buff, size_t size, int flag, (struct sockaddr*)src_addr, int *addr_len);
int sendto(int sockfd, void *buff,size_t size, int flag, (struct sockaddr*)src_addr, int addr_len);
int close(int fd);
三、TCP与UDP的区别:
| TCP | UDP |
是否连接 | 面向连接的 | 无连接的 |
可靠性 | 可靠的 | 不可靠的 |
服务类型 | 字节流服务 | 数据报服务 |
传输速度 | 慢 | 快 |
适用场景 | 一对一 | 广播,多播 |
TCP和UDP发送数据的方式:
TCP字节流服务:发送端应用程序连续执行多次写操作时,TCP模块先将这些数据放入TCP发送缓冲区中,当TCP模块真正开始发送数据时,发送缓冲区中这些等待发送的数据可能被封装成一个或多个TCP报文段发出。TCP模块发送出的TCP报文段的个数与应用程序执行的写操作次数之间没有关系。当接收端收到一个或多个TCP报文段后,TCP模块将它们携带的应用程序数据按照TCP报文段的序号(见后文)依次放人TCP接收缓冲区中,并通知应用程序读取数据。接收端应用程序可以一次性将TCP接收缓冲区中的数据全部读出,也可以分多次读取,这取决于用户指定的应用程序读缓冲区的大小。因此,应用程序执行的读操作次数和TCP模块接收到的TCP报文段个数之间也没有固定的数量关系。
UDP 数据报服务:发送端应用程序每执行次写操作, UDP模块就将其封装成一个UDP数据报并发之。接收端必须及时针对每一个UDP数据报执行读操作(通过recvfrom系统调用),否则就会丢包(这经常发生在较慢的服务器上).并且如果用户没有指定足够的应用程序缓冲区米读取UDP数据,则UDP数据将被截断。如果接收方一次没有接收完,余下的数据报将会被丢弃。