• 37 网络相关函数(五)——live555源码阅读(四)网络


    37 网络相关函数(五)——live555源码阅读(四)网络

    本文由乌合之众 lym瞎编,欢迎转载 blog.cnblogs.net/oloroso
    本文由乌合之众 lym瞎编,欢迎转载 my.oschina.net/oloroso

    简介

    网络相关函数是一系列用于操作网络数据的函数。在多个文件中都有相关的函数的定义。还有一些函数是系统socket API相关函数,就不提了。
       这一系列的函数大多有一个特点,需要一个UsageEnvironmet&型的参数。
       这些方法大多在live555sourcecontrolgroupsockincludeGroupsockHelper.hh中声明。

    10)MAKE_SOCKADDR_IN构建sockaddr_in结构体宏

     1 #ifdef HAVE_SOCKADDR_LEN
     2 #define SET_SOCKADDR_SIN_LEN(var) var.sin_len = sizeof var
     3 #else
     4 #define SET_SOCKADDR_SIN_LEN(var)
     5 #endif
     6 
     7 // sockaddr_in var,使用adr和prt为其赋值(AF_INET)
     8 #define MAKE_SOCKADDR_IN(var,adr,prt) /*adr,prt must be in network order*/
     9     struct sockaddr_in var;
    10     var.sin_family = AF_INET;
    11     var.sin_addr.s_addr = (adr);
    12     var.sin_port = (prt);
    13     SET_SOCKADDR_SIN_LEN(var);

    11)setupDatagramSocket设置数据报套接口

    setupDatagramSocket函数有两个参数(UsageEnvironment& env, Port port)。根据envgroupsockPriv成员来确定重用标识。如果groupsockPriv为空则使用默认设置。

    setupDatagramSocket创建一个数据报形式的socket套接口,如果端口port 0,且ReceivingInterfaceAddrINADDR_ANY的时候,不进行绑定(bind)。否则若port==0的时候,绑定ReceivingInterfaceAddr(不为INADDR_ANY)和端口0(内核选择端口)。不为0的时候绑定INADDR_ANY(内核选择IP)和端口port

    绑定完成之后设置多播发生接口。如果全局的SendingInterfaceAddr== INADDR_ANY则不设置。
    函数成功返回一个socket套接口句柄,失败返回-1

     1 // 设置数据报套接字
     2 int setupDatagramSocket(UsageEnvironment& env, Port port) {
     3     // 初始化网络
     4     if (!initializeWinsockIfNecessary()) {
     5         socketErr(env, "Failed to initialize 'winsock': ");
     6         return -1;
     7     }
     8     // 创建数据报套接字
     9     int newSocket = createSocket(SOCK_DGRAM);
    10     if (newSocket < 0) {
    11         socketErr(env, "unable to create datagram socket: ");
    12         return newSocket;
    13     }
    14     // 获取env的groupsockPriv重新使用标识
    15     int reuseFlag = groupsockPriv(env)->reuseFlag;
    16     // 根据需要,为env释放groupsockPriv成员指向对象
    17     reclaimGroupsockPriv(env);
    18 
    19     // 设置允许重用本地地址和端口,reuseFlag用来接受传出值
    20     if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEADDR,
    21         (const char*)&reuseFlag, sizeof reuseFlag) < 0) {
    22         socketErr(env, "setsockopt(SO_REUSEADDR) error: ");
    23         closeSocket(newSocket);
    24         return -1;
    25     }
    26 
    27 #if defined(__WIN32__) || defined(_WIN32)
    28     // Windoze doesn't properly handle SO_REUSEPORT or IP_MULTICAST_LOOP
    29     // win-doze 贬义,可能是由于操作系统BUG很多,而且运行速度慢,导致在运行的是后你会DOZE(打瞌睡)
    30     // Windows无法正确的处理SO_REUSEPORT或 IP_MULTICAST_LOOP
    31 #else
    32 #ifdef SO_REUSEPORT     //在定义了重新使用端口宏下设置
    33     if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEPORT,
    34         (const char*)&reuseFlag, sizeof reuseFlag) < 0) {
    35         socketErr(env, "setsockopt(SO_REUSEPORT) error: ");
    36         closeSocket(newSocket);
    37         return -1;
    38     }
    39 #endif
    40 
    41 #ifdef IP_MULTICAST_LOOP    //在定义了IP多播循环下设置
    42     const u_int8_t loop = 1;
    43     if (setsockopt(newSocket, IPPROTO_IP, IP_MULTICAST_LOOP,
    44         (const char*)&loop, sizeof loop) < 0) {
    45         socketErr(env, "setsockopt(IP_MULTICAST_LOOP) error: ");
    46         closeSocket(newSocket);
    47         return -1;
    48     }
    49 #endif
    50 #endif
    51     // Note: Windoze requires binding, even if the port number is 0
    52     // Windows 需要绑定,即使端口号是0
    53     netAddressBits addr = INADDR_ANY;   // 设置绑定地址是任意网口IP
    54 #if defined(__WIN32__) || defined(_WIN32)
    55 #else
    56     if (port.num() != 0 || ReceivingInterfaceAddr != INADDR_ANY) {
    57         //ReceivingInterfaceAddr是一个全局的定义,默认是INADDR_ANY
    58 #endif
    59         if (port.num() == 0) addr = ReceivingInterfaceAddr;
    60         // 组建sockaddr_in结构体
    61         MAKE_SOCKADDR_IN(name, addr, port.num());
    62         // 绑定socket套接口和sockaddr地址
    63         if (bind(newSocket, (struct sockaddr*)&name, sizeof name) != 0) {
    64             char tmpBuffer[100];
    65             sprintf(tmpBuffer, "bind() error (port number: %d): ",
    66                 ntohs(port.num()));
    67             socketErr(env, tmpBuffer);
    68             closeSocket(newSocket);
    69             return -1;
    70         }
    71 #if defined(__WIN32__) || defined(_WIN32)
    72 #else
    73     }
    74 #endif
    75 
    76     // Set the sending interface for multicasts, if it's not the default:
    77     // 设置多播发送接口,如果它不是默认的:
    78     if (SendingInterfaceAddr != INADDR_ANY) {
    79         struct in_addr addr;
    80         addr.s_addr = SendingInterfaceAddr;
    81         // 设置多播接口
    82         if (setsockopt(newSocket, IPPROTO_IP, IP_MULTICAST_IF,
    83             (const char*)&addr, sizeof addr) < 0) {
    84             socketErr(env, "error setting outgoing multicast interface: ");
    85             closeSocket(newSocket);
    86             return -1;
    87         }
    88     }
    89 
    90     return newSocket;
    91 }
  • 相关阅读:
    图论初步
    分块和块状链表
    线段树入门
    ST表与树状数组
    [luogu P1312]Mayan游戏
    [luoguP4139]上帝与集合的正确用法


    电解质
    无机盐
  • 原文地址:https://www.cnblogs.com/oloroso/p/4724375.html
Copyright © 2020-2023  润新知