【网络编程】UDP|TCP拥塞控制

UDP:(主要问TCP和UDP的区别)
使用UDP还是TCP看数据可不可以丢。
例如客户端–服务器
UDP 可以直接 多个客户端给服务器发送数据,且服务器可以收到,因为不需要建立连接。
并且,服务器关闭,不关闭客户端,再次打开服务器,客户端仍然可以将数据把给服务器。
客户端发给服务器 的数据,如果服务器收不完,会直接丢掉。(每个数据包都会独立发送,)只要告诉目的端口,给谁都能发数据。
(如果数据丢失,可靠性在应用层实现)
请添加图片描述
ser.c

include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
//inet
int main()
{
   int sockfd = socket(AF_INET,SOCK_DGRAM,0);
   if(sockfd == -1)
   {
           exit(1);
   }
   struct sockaddr_in saddr,caddr;
   memset(&saddr,0,sizeof(saddr));//因为有第四个元素,需要置0,所以所兴都置为0;
   saddr.sin_family = AF_INET;
   saddr.sin_port = htons(6000); //
   saddr.sin_addr.s_addr = inet_addr("0.0.0.0");//字符串转为无符号整形


   int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
    if(res == -1)
    {
            printf("bind error\n");
             exit(1);
    }
   while(1){
            char buff[128] = {0};
            int len = sizeof(caddr);
            recvfrom(sockfd,buff,127,0,(struct sockaddr*)&caddr,&len);
                                            //无符号整形专成字符串     无符号整形转字符串(打印点分十进制)
            printf("port: %d,ip: %s,buff:%s\n",ntohs(caddr.sin_port),inet_ntoa(caddr.sin_addr),buff);
            sendto(sockfd,"ok",2,0,(struct sockaddr*)&caddr,sizeof(caddr));
 }
}

cli.c

#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

int main()
{ 
        int sockfd = socket(AF_INET,SOCK_DGRAM,0);
        if(sockfd == -1)
        {
                 exit(1);
         }

        struct sockaddr_in saddr;
        saddr.sin_family = AF_INET;
        saddr.sin_port = htons(6000);
        saddr.sin_addr.s_addr = inet_addr("0.0.0.0");

        while(1)
        {
                char buff[128] = {0};
                fgets(buff,128,stdin);
                if(strncmp(buff,"end",3)==0)
                {
                        break;
                }
                sendto(sockfd,buff,strlen(buff)-1,0,(struct sockaddr*)&saddr,sizeof(saddr));
                memset(buff,0,128); 
                int len = sizeof(saddr);
                recvfrom(sockfd,buff,127,0,(struct sockaddr*)&saddr,&len);
                printf("recv:%s\n",buff);
        }
        close(sockfd);
        exit(0);
 }

《云服务器》使用

滑动窗口:

《计算机网络》5.7.1

超时重传的时间选择

必须考虑传输效率(三种传输机制)【坐公交】

TCP通过Nagle算法如何控制传输《TCP-IP详解卷一:协议》19章

  1. TCP维持一个变量,达到最大报文段MSS,就发送(延迟高)
  2. 由发送方指明要求发送报文段(TCP支持的推送操作)
  3. 发送方的计时器时限到了,这时就把已经有的缓存数据装入报文段,发送出去。
    糊涂窗口综合征 :接收方从接收缓冲区一次仅读一个数据(一次仅腾出一个空间),向发送方确认,将发送窗口设置为1,但是发送方由40个字节,那就只能一写,一读。造成延迟,网络效率低。
    解决方案:等接收方读取数据,腾出足够空间(容纳最长的报文段,或有一半空间空闲)
    设置一个计时器:主动询问接收缓存区是否已满。

TCP 拥塞控制

前提:网络能够承受现有的网络负荷(全局性过程)交通堵不堵,取决于所有人。
拥塞控制:就是防止过多的数据注入到网络,使得网络中的路由器或者链路不会过载
发送端用发送窗口(SWND)限制了能连续发送给接收端的报文段数量
SWND 太小:网络延迟
SWND太大:网络拥塞。(连续发送的报文段太多)
接收端通过通知窗口(RWND)来控制发送窗口的(SWND)
SWND = min(拥塞窗口(CWND)和接收窗口(RWND)

  • 慢启动和拥塞避免
    慢启动:TCP模块刚启动发送数据的时候,并不知道网络的情况,因此以一种试探的方式,平滑的增加(指数增大) CWND的值。
    (慢启动并不慢,如果不加以控制,就会造成网络拥塞)因此,设置慢启动门限,当拥塞窗口(CWND)达到这个值,就会进入拥塞避免状态。
    拥塞避免:拥塞避免算法CWND以线性 (加法)增发,扩展变慢
    如下图:请添加图片描述

1.处理第一种拥塞,或者2发生在TCP重传定时器溢出的后面,也会处理2。
2.如果发生的是传送超时,那么会重传报文段,并且重传的方式会进行调整。最终拥塞控制进入慢启动阶段。

  • 如何判断拥塞?
  1. 传送超时,TCP重传定时器溢出。
  2. 接收到重复的确认报文段。
  • 快速重传和快速恢复
    超时重传发生在超时之后
    快速重传发生在超时之前。
    超时重传:如果发送端连续收到三个重复确认报文段,便会执行重传。
    请添加图片描述

快速恢复:当拥塞时,CWND发送减少为一半,如果仍然拥塞,减少为1半 的一半。(就不会进入慢启动阶段)
如下图:请添加图片描述

(快速重传和快速恢复完成后将进入拥塞避免状态)
处理第2种情况。
例如 TCP报文段丢失,或者接收端收到乱序的TCP报文段并重排。
拥塞控制算法:判断当收到TCP的确认报文段,网络是否真的拥塞。
或者TCP报文段是否真的丢失?
如果发送端连续收到三个重复确认报文段,则认为网络拥塞。立即启动快速重传和快速恢复,完成之后将进入拥塞避免状态。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值