风吹过


以前,晚餐后在学校田径场的大榕树下,散散步吹吹风,累了就去图书馆看看书,感觉真好。


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

[TOC] 博客园文章地址 http://www.cnblogs.com/oloroso/archive/2015/08/17/4736793.html

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;

}