unix网络编程笔记一

UDP和TCP介绍

udp和tcp是网络中传输层的两个协议,udp是数据包套接字,是不安全的只管发不在意目标是否成功接收是否出错等情况,tcp是传输控制协议,是流式套接字,有差错检测超时重传和错误处理等机制,可以认为是安全的。

tcp虽然是安全的,但是这种安全是需要牺牲效率的,tcp协议在其中添加了很多的字段来保证数据的正确传输,因此tcp通常使用在对数据安全性较高的应用中。

udp虽然是不安全的,但是优点是传输效率高,延迟小通常使用在对数据的安全性要求不高的应用中,比如观看视频和视频电话时都是使用udp协议的。

tcp的三次握手

在这里插入图片描述三次握手的过程

  1. 首先需要服务器端开启监听连接,客户端调用connect函数进行主动连接,此时客户端需要发送一个SYN请求连接的数据包,序号seq=J。
  2. 服务器的监听套接字监听到这个连接的请求,向客户端发送一个SYN和ACK对客户端进行响应。
  3. 客户端接收到服务器的SYN和ACK,客户端表示连接完成,并向服务器发送一个ACK确认包。
  4. 服务器接收客户端发送的ACK包,则服务器建立和客户端的连接。

TCP的四次挥手

在这里插入图片描述

  1. 客户端调用close函数关闭连接,客户端主动关闭连接,则客户端发送一个FIN的数据包,携带一个序号M。
  2. 服务器端接收到客户端发送的FIN数据包,则产生一个EOF来表示结束,服务器向客户端发送一个ACK表示已经接收到FIN包。
  3. 当服务器读取到EOF时便会向客户端发送一个FIN。
  4. 客户端读取服务器发送的FIN,并向服务器发送一个ACK包表示确定,客户端关闭连接。
  5. 服务器接收到客户端发送的ACK,服务器关闭和客户端的连接。

TCP的状态

下面是一个TCP连接和关闭的状态图

状态转换图当客户端主动连接时状态的变化

  1. 客户端发送一个FIN报文,此时客户机的状态为SYN_SEND状态。
  2. 客户端接收到服务器端发送来的SYN和ACK时,此时客户端的状态由SYN_SENT状态转变为ESTABLISHED状态,表示连接的建立。

当服务器端被动连接时状态的变化

  1. 开始时服务器处于LISTEN状态的,表示等待客户端的连接,当接收的FIN报文时由LISTEN转变为SYN_RCVD状态。
  2. 当接收到客户端发送的ACK时,由SYN_RCVD状态转变为ESTABLISHED,表示连接的建立。

当客户端主动关闭连接时状态的变化

  1. 开始时客户端处于ESTABLISHED状态,当客户端调用close函数表示主动关闭连接时,状态从ESTABLISHED变为FIN_WAIT_1状态。
  2. 当客户端接收到对FIN的应答的ACK报文时,状态从FIN_WAIT_1变为FIN_WAIT_2状态。
  3. 当客户端接收到服务器由于调用close而产生的FIN时,状态从FIN_WAIT_2变为TIME_WAIT状态。

当服务器被动关闭连接时状态的改变

  1. 开始时服务器处于ESTABLISHED状态,当接收到客户端的FIN时,由ESTABLISHED变为CLOSE_WAIT状态。
  2. 当服务器由于执行close而产生一个发向客户端的包时,状态由CLOSE_WAIT变为LAST_ACK状态,表示再接收到一个对这个报文的ACK包便可以关闭连接了。
  3. 服务器接收到对自己FIN的确定包ACK,由CLOSE_WAIT状态变为CLOSED状态,表示已经关闭连接。

这几个状态的变化很重要,对我们编写健壮的代码是必不可少缺的。

TIME_WAIT状态

从上面可以看出客户端主动关闭连接,但是客户端的最终状态却是TIME_WAIT,并不是closed。TIME_WAIT状态的存在是很有必要的,下面我们来做出解释。

我们假设这么一种情况,当客户端对服务器的最后一个ACK在传输中丢失时,服务器会再一次发送FIN,如果此时客户端的状态是closed状态,则客户端会对服务器发送一个RST,这个会导致服务器错误。因此使用TIME_WAIT状态可以防止最后一个ACK丢失而造成服务器的错误。

还有一种情况,当一个连接已经关闭时,再次连接时,如果连接的端口号和上一次是一致的,当第一次连接中有重复发送的报文时,那么这个报文便会被第二个连接所接收,这是所不允许的,使用TIME_WAIT可以有效避免这种情况,因为TIME_WAIT维持的时间内是不会建立新的连接的,并且维持的长度为2MSL,MSL为数据包的最大生存时间,重复的数据包会在这段时间内被丢弃,因此不会出现第一个连接的报文被第二次接收的情况。

端口号

众所周知端口号 0~1023
已登记的端口号 1024~49151
动态的端口号 49152~65535

服务器是提供服务的,每种服务对应一个端口号,服务器使用的众所周知的端口号eg:80 21 22 …

客户端在访问服务器时会随机选取一个动态的端口作为源端口

四元组 源ip 源端口号 目的ip 目的端口号

TCP的输出

下面是tcp输出的过程图
在这里插入图片描述调用write函数将应用缓冲区的内容写入套接字缓冲区,write默认是阻塞的,当套接字缓冲区已满时,write不会反回,直到将所有的数据写入套接字缓冲区。可以看出调用write成功并不是已经发送数据成功,只是将数据发送到套接字缓冲区中。

TCP是可靠的,在套接字缓冲区中会保留已经返送但是还没有确认的数据,防止目的主机没有正确收到数据,还可以重传数据。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值