如何使用TOS设置消息优先级?

时间:2012-07-11 09:18:44

标签: c linux sockets network-programming

IP标头具有服务类型(TOS)字段。它可用于设置有类排队规则,即PRIO。

我测试了以下代码。

#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc, char**argv)
{
   int listenfd, connfd, optval;
   struct sockaddr_in servaddr, cliaddr;
   socklen_t clilen;
   pid_t     childpid;
   char      mesg[16];

   listenfd = socket(AF_INET, SOCK_STREAM, 0);

   bzero(&servaddr, sizeof(servaddr));
   bzero(mesg, 0, sizeof(mesg));
   servaddr.sin_family = AF_INET;
   servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
   servaddr.sin_port = htons(32000);
   bind(listenfd,(struct sockaddr *)&servaddr, sizeof(servaddr));

   listen(listenfd, 1024);

   for (;;)
   {
      clilen = sizeof(cliaddr);
      connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen);

      if ((childpid = fork()) == 0)
      {
         close(listenfd);

         for (;;)
         {
            optval = 0x28;
            setsockopt(cliaddr, IPPROTO_IP, IP_TOS, &optval, sizeof(optval));
            strcpy(mesg, "tos=0x28");
            sendto(connfd, mesg, sizeof(mesg), 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr));
            sleep(2);

            optval = 0x58;
            strcpy(mesg, "tos=0x58");
            setsockopt(cliaddr, IPPROTO_IP, IP_TOS, &optval, sizeof(optval));
            sendto(connfd, mesg, sizeof(mesg), 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr));
            sleep(2);
         }

      }

      close(connfd);
   }
}

可以在TOS字段设置成功的情况下发送数据包。但是,如何使消息优先级生效呢?谢谢!

2 个答案:

答案 0 :(得分:1)

TOS是对路由器的指令。它没有任何效果,除非路径中的所有路由器都同意它的含义,将其完整地传递给下一个路由器,并自己做一些事情。他们呢?如果路径中没有路由器则根本没有影响。

答案 1 :(得分:0)

TOS领域的一个重要特征是沿途的路由器可以根据TOS字段对数据包进行优先级排序。

使用TOS字段的另一个重要影响是在本地计算机内。例如,在Linux内核中,网络律师有一些称为Traffic Control的东西,它会限制或重新排序传出的IP流量。 Linux 2.2+上的默认行为称为 pfifo_fast ,它包含三个用于传出流量的独立队列(或带)。每个队列的优先级高于下一个队列,这意味着在队列1的任何内容被推送到网络之前,队列0的所有流量都会被推出。 TOS字段用于确定将传出的IP数据包放入哪个队列。有关详细信息,请查看here。小心使用TC功能,您可以轻松地削弱计算机。我建议使用虚拟机。

我不确定非Linux平台是否存在此行为。