tcp/udp协议学习及项目问题解决

前言:
	项目调试中遇到客户端与服务器握手失败的情况,自检代码没有问题,百思不得其解,  
	最后抓包发现最后一包ack没有回复导致。 
	因此记录下该问题,顺便回顾了下之前学习的网络协议知识。

tcp协议学习

	tcp和udp是OSI模型中的运输层中的协议。tcp提供可靠的通信传输,而udp则是将广播和细节控制交给应用决策的通信传输。

一、 优点

 1.tcp连接可靠,稳定。点对点连接。每次发起连接都会有三次握手来建立连接。
 2.TCP充分实现了数据传输时各种控制功能,可以进行丢包的重发控制,还可以对次序乱掉的分包进行顺序控制。
 3.TCP作为一种面向有连接的协议,只有在确认通信对端存在时才会发送数据,从而可以控制通信流量的浪费。在数据传完后,还会断开连接用来节约系统资源。
 4.TCP通过检验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现可靠性传输

二、缺点

1.慢,效率低,占用系统资源高,易被攻击 。tcp在传递数据之前,要先建连接,这会消耗时间,而且在数据传递时,确认机制、重传机制、拥塞控制机制等都会消耗大量的时间。
2.要在每台设备上维护所有的传输连接,事实上,每个连接都会占用系统的CPU、内存等硬件资源

三、客户端/服务器建立的一般步骤:

服务器:
  1、创建一个socket,用函数socket(); 
  2、设置socket属性,用函数setsockopt(); * 可选 
  3、绑定IP地址、端口等信息到socket上,用函数bind(); 
  4、开启监听,用函数listen(); 
  5、接收客户端上来的连接,用函数accept(); 
  6、收发数据,用函数send()和recv(),或者read()和write(); 
  7、关闭网络连接; 
  8、关闭监听;
客户端:
  1、创建一个socket,用函数socket(); 
  2、设置socket属性,用函数setsockopt();* 可选 
  3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选 
  4、设置要连接的对方的IP地址和端口等属性; 
  5、连接服务器,用函数connect(); 
  6、收发数据,用函数send()和recv(),或者read()和write(); 
  7、关闭网络连接;

四 TCPIP保活机制

保活机制:

1.保活机制是一种在不影响数据流内容情况下保持两端连接存在的一种方式,类似于我们常说的心跳包机制。
2.它是由一个保活计时器实现的。当计时器被激发, 连接端将发送一个保活探测(简称保活)报文 , 另一端接收报文的同时会发送一个ACK作为响应。
3.如果发送端没有收到响应报文,那么经过一个已经提前配置好的保活时间间隔(keepalive interval),将继续发送保活探测报文,直到发送探测报文的次数达到保活探测数(keepalive probe),这时对方主机将被确认为不可到达,连接将被中断。

功能开启的好处

TCP保活功能在工作过程中, 开启该功能的一端(客户端)会发现另一端(服务器)处于以下四种状态之一:
1.服务器正常工作,并且可以到达。此时客户端将保活计时器重置。
2.服务器崩溃,不再响应ack包。客户端不会接收到响应报文,并在经过保活时间间隔指定的时间后超时。超时前,客户端会持续发送探测报文,一共发送保活探测数指定次数的探测报文,如果客户端没有收到任何探测报文的响应,则认为服务器已经关闭,连接也将断开。
3.服务器崩溃和已重新启动。在这种情况下,客户端响应是一个重置报文段,客户端将会断开连接
4.服务器仍在工作,但是由于某些原因无法到达客户端(例如网络无法传输,而且可能使用ICMP通知也可能不通知对方这一事实)。

保活机制设置

1.设置SO_KEEPALIVE选项,将这个选项设置为1,代表打开KeepAlive机制。
2.设置TCP_KEEPIDLE选项,值为5秒,代表如果TCP连接上有五秒钟没有任何数据包传输,则启动保活机制,发送TCP Keep-alive机制。默认为2小时。
3.设置TCP_KEEPINTVL选项,值为1秒,代表如果启动保活机制,则每隔1秒发送一个Keep-alive包。默认为75秒。
4.设置TCP_KEEPCNT选项,值为3,代表如果对端对3次Keep-alive数据包都没有正常响应,则判断对端已经崩溃。默认为9

下边是常见的代码配置片段:

int keep_alive = 1;
int keep_idle = 5, keep_interval = 1, keep_count = 3;
int ret = 0;
 
if (-1 == (ret = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keep_alive,
    sizeof(keep_alive)))) {
    fprintf(stderr, "[%s %d] set socket to keep alive error: %s", __FILE__,
        __LINE__, ERRSTR);
}
if (-1 == (ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &keep_idle,
    sizeof(keep_idle)))) {
    fprintf(stderr, "[%s %d] set socket keep alive idle error: %s", __FILE__,
        __LINE__, ERRSTR);
}
if (-1 == (ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &keep_interval,
    sizeof(keep_interval)))) {
    fprintf(stderr, "[%s %d] set socket keep alive interval error: %s", __FILE__,
        __LINE__, ERRSTR);
}
if (-1 == (ret = setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &keep_count,
    sizeof(keep_count)))) {
    fprintf(stderr, "[%s %d] set socket keep alive count error: %s", __FILE__,
        __LINE__, ERRSTR);

项目中出现过的问题:

项目背景介绍:

因某客户需求,设备无sim卡无法使用短信业务,需要通过tcpip网络通信方式向监控平台开站上报所需内容信息。

项目问题及现象描述:

tcpip连接不稳定
通过wireshark工具抓包发现握手期间第三次握手客户端发的纯ack包没有被服务器接收到,重传过后依然没有收到,导致服务器触发RST。

解决方案:

由于tcp是累加ack,而且ack在tcp包头,也就是所有tcp包都应该带有ack数据,中间丢一个纯ack包,应该是不会影响到tcp通讯的,所以只要后面带数据的ack,能ack到上次的syn包,理论上依然可以表示握手成功,建立通信。事实证明,此方案确实可行

udp协议学习

一、优点

1.udp速度快,不提供复杂的控制机制,利用IP提供面向无连接的通信服务。并且它是将应用程序发来的数据在收到的那一刻,立刻按照原样发送到网络上的一种机制。
2.有些应用场景对可靠性要求不高会用到UPD,比如长视频,要求速率

二、缺点

1.网络拥堵的情况下,udp也无法进行流量控制等避免网络拥塞的行为。
2.此如果传输途中出现了丢包,udp也不负责重发。甚至当出现包的到达顺序乱掉时也没有纠正的功能。
3.udp将部分控制(丢包重发或顺序到达)转移到应用程序去处理,自己却只提供作为传输层协议的最基本功能。udp有点类似于用户说什么听什么的机制,但是需要用户充分考虑好上层协议类型并制作相应的应用程序。

三、应用场景:

  1.面向数据报的连接
  2.网络数据大多为短消息时 
  3.客户端较多时
  4.对数据安全性无特殊要求
  5.网络负担非常重,但对响应速度要求高

四、客户端/服务器建立的一般步骤:

服务器:
  1、创建一个socket,用函数socket(); 
  2、设置socket属性,用函数setsockopt();* 可选 
  3、绑定IP地址、端口等信息到socket上,用函数bind(); 
  4、循环接收数据,用函数recvfrom(); 
  5、关闭网络连接; 
客户端:
  1、创建一个socket,用函数socket(); 
  2、设置socket属性,用函数setsockopt();* 可选 
  3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选 
  4、设置对方的IP地址和端口等属性; 
  5、发送数据,用函数sendto(); 
  6、关闭网络连接;

小结

1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的(发送数据之前不需要建立连接)
2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的,UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
5、TCP首部开销20字节;UDP的首部开销小,只有8个字节
6、TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值