38 网络相关函数(六)——live555源码阅读(四)网络

38 网络相关函数(六)——live555源码阅读(四)网络

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

简介

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

12)makeSocketNonBlocking和makeSocketBlocking套接口阻塞属性设置

makeSocketNonBlocking函数用于为参数sock代表的套接口添加O_NONBLOCK非阻塞属性。

// 设置sock为非阻塞模式
Boolean makeSocketNonBlocking(int sock) {
#if defined(__WIN32__) || defined(_WIN32)
    unsigned long arg = 1;
    return ioctlsocket(sock, FIONBIO, &arg) == 0;
#elif defined(VXWORKS)
    int arg = 1;
    return ioctl(sock, FIONBIO, (int)&arg) == 0;
#else
    int curFlags = fcntl(sock, F_GETFL, 0);
    return fcntl(sock, F_SETFL, curFlags|O_NONBLOCK) >= 0;
#endif
}

makeSocketBlocking函数用于为参数sock代表的套接口去除O_NONBLOCK非阻塞属性。

// 设置sock为阻塞模式
Boolean makeSocketBlocking(int sock) {
#if defined(__WIN32__) || defined(_WIN32)
    unsigned long arg = 0;
    return ioctlsocket(sock, FIONBIO, &arg) == 0;
#elif defined(VXWORKS)
    int arg = 0;
    return ioctl(sock, FIONBIO, (int)&arg) == 0;
#else
    int curFlags = fcntl(sock, F_GETFL, 0);
    return fcntl(sock, F_SETFL, curFlags&(~O_NONBLOCK)) >= 0;
#endif
}

13)setupStreamSocket设置流式套接口

setupStreamSocketsetupDatagramSocket的功能很像,区别在于这里返回的是一个流式套接口。
makeNonBlocking参数用于控制创建的套接口是否是阻塞的。

// 设置流式套接字
int setupStreamSocket(UsageEnvironment& env,
    Port port, Boolean makeNonBlocking) {
    if (!initializeWinsockIfNecessary()) {
        socketErr(env, "Failed to initialize 'winsock': ");
        return -1;
    }

    int newSocket = createSocket(SOCK_STREAM);
    if (newSocket < 0) {
        socketErr(env, "unable to create stream socket: ");
        return newSocket;
    }

    int reuseFlag = groupsockPriv(env)->reuseFlag;
    reclaimGroupsockPriv(env);
    if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEADDR,
        (const char*)&reuseFlag, sizeof reuseFlag) < 0) {
        socketErr(env, "setsockopt(SO_REUSEADDR) error: ");
        closeSocket(newSocket);
        return -1;
    }

    // SO_REUSEPORT doesn't really make sense for TCP sockets, so we
    // normally don't set them.  However, if you really want to do this
    // #define REUSE_FOR_TCP
#ifdef REUSE_FOR_TCP
#if defined(__WIN32__) || defined(_WIN32)
    // Windoze doesn't properly handle SO_REUSEPORT
#else
#ifdef SO_REUSEPORT
    if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEPORT,
        (const char*)&reuseFlag, sizeof reuseFlag) < 0) {
        socketErr(env, "setsockopt(SO_REUSEPORT) error: ");
        closeSocket(newSocket);
        return -1;
    }
#endif
#endif
#endif

    // Note: Windoze requires binding, even if the port number is 0
#if defined(__WIN32__) || defined(_WIN32)
#else
    if (port.num() != 0 || ReceivingInterfaceAddr != INADDR_ANY) {
#endif
        MAKE_SOCKADDR_IN(name, ReceivingInterfaceAddr, port.num());
        if (bind(newSocket, (struct sockaddr*)&name, sizeof name) != 0) {
            char tmpBuffer[100];
            sprintf(tmpBuffer, "bind() error (port number: %d): ",
                ntohs(port.num()));
            socketErr(env, tmpBuffer);
            closeSocket(newSocket);
            return -1;
        }
#if defined(__WIN32__) || defined(_WIN32)
#else
    }
#endif
    // 根据参数设置是否为非阻塞
    if (makeNonBlocking) {
        if (!makeSocketNonBlocking(newSocket)) {
            socketErr(env, "failed to make non-blocking: ");
            closeSocket(newSocket);
            return -1;
        }
    }

    return newSocket;
}
posted @ 2015-08-17 15:47  乌合之众  阅读(788)  评论(0编辑  收藏  举报
clear