⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 udpstack.cxx

📁 RTP协议
💻 CXX
📖 第 1 页 / 共 3 页
字号:
    struct sockaddr dummyAddr;    memset((char*) &dummyAddr, 0, sizeof(dummyAddr));    dummyAddr.sa_family = NetworkConfig::instance().getAddrFamily();    int result;    if ((result = connect(data->socketFd,                          (struct sockaddr*) & dummyAddr,                          sizeof(dummyAddr))) != 0)    {        int err = errno;        strstream errMsg;        errMsg << "UdpStack<" << getLclName() << " " << getRmtName()        << ">::UdpStack error during socket connect: ";        errMsg << strerror(err);        errMsg << char(0);        cpLog(LOG_ERR,  errMsg.str());        errMsg.freeze(false);#if 0        throw UdpStackException(errMsg.str());        assert(0);#endif    }    dummyAddr.sa_family = AF_UNSPEC;    if ((result = connect(data->socketFd,                          (struct sockaddr*) & dummyAddr,                          sizeof(dummyAddr))) != 0)    {        int err = errno;        strstream errMsg;        errMsg << "UdpStack<" << getLclName() << " " << getRmtName()        << ">::UdpStack error during socket connect: ";        errMsg << strerror(err);        errMsg << char(0);        cpLog(LOG_ERR, errMsg.str());        errMsg.freeze(false);#if 0        throw UdpStackException(errMsg.str());        assert(0);#endif    }}/// set the local ports/// The first time change from inactive to recvonly/sendrecv or/// change the local ports, this method needs to be called.voidUdpStack::setLocal (const int minPort, int maxPort ){    cpLog (LOG_DEBUG_STACK, "UdpStack::setLocal");    cpLog (LOG_DEBUG_STACK, "minPort = %d, maxPort = %d", minPort, maxPort);    if ((mode == sendonly) || (mode == inactive))    {        cpLog(LOG_ERR, "The UdpStack is sendonly or inactive.");        return ;    }    // To reopen a new socket, since after sendto(), bind() will fail    //    if (localPort != -1)    {        int newFd;        newFd = socket(NetworkConfig::instance().getAddrFamily(),                        SOCK_DGRAM, IPPROTO_UDP);        if(NetworkConfig::instance().getAddrFamily() == AF_INET6)        {            //Set the sockoption so that we get get source IP            //when running on the same host            int on=1;            setsockopt(data->socketFd, IPPROTO_IPV6, IPV6_PKTINFO, &on, sizeof(on));        }#ifndef WIN32        if ( close (data->socketFd) != 0 )#else	if ( closesocket(data->socketFd) )#endif	{            cpLog(LOG_ERR, "close socketFd error!");	}        data->socketFd = newFd;        if ( data->socketFd < 0 )        {            int err = errno;            strstream errMsg;            errMsg << "UdpStack<" /* << getLclName() */            << ">::UdpStack error during socket creation: ";            errMsg << strerror(err);            errMsg << char(0);            cpLog(LOG_ERR,  errMsg.str());            throw UdpStackException(errMsg.str());            errMsg.freeze(false);            assert(0);        }#ifdef __linux__        int buf1 = 1;        int len1 = sizeof(buf1);        struct protoent * protoent;        protoent = getprotobyname("icmp");        if (!protoent)        {            fprintf(stderr, "Cannot get icmp protocol\n");        }        else        {            if (setsockopt(data->socketFd, protoent->p_proto, SO_BSDCOMPAT,                           (char*)&buf1, len1)                    == -1)            {                fprintf(stderr, "setsockopt error SO_BSDCOMPAT :%s",                        strerror(errno));            }        }#endif    }    doServer(minPort, maxPort);}/// set the default destinationvoidUdpStack::setDestination ( const NetworkAddress* host ){    if ((mode == recvonly) || (mode == inactive))    {        cpLog(LOG_ERR, "The UdpStack is recvonly or inactive.");        return ;    }    doClient(host);}voidUdpStack::setDestination ( const char* host, int port ){    assert(host);    NetworkAddress netAddress;    if ( host )    {        string rHostName = host;        netAddress.setPort(port);        netAddress.setHostName(rHostName);    }    setDestination (&netAddress);}intUdpStack::getRxPort() {        	cpLog(LOG_DEBUG_STACK, "getRxPort()");		char service[6];		if(getnameinfo((struct sockaddr *)data->localAddr, sizeof(*data->localAddr), NULL, 0, service, sizeof(service), NI_NUMERICSERV | NI_NUMERICHOST))			perror("getnameinfo");		return atoi(service);}intUdpStack::getTxPort() {        	cpLog(LOG_DEBUG_STACK, "getTxPort()");		char service[6];		if(getnameinfo((struct sockaddr *)data->remoteAddr, sizeof(*data->remoteAddr), NULL, 0, service, sizeof(service), NI_NUMERICSERV | NI_NUMERICHOST))			perror("getnameinfo");		return atoi(service);        };/// need to delete the ne wobject after the object is usedNetworkAddress *UdpStack::getDestinationHost () const{	char host[256];	char port[6];    if(getnameinfo((struct sockaddr *)data->remoteAddr, sizeof(*data->remoteAddr), host, sizeof(host), port, sizeof(port), NI_NUMERICSERV | NI_NUMERICHOST))	    perror("getnameinfo");    NetworkAddress* desHost = new NetworkAddress(host, atoi(port)) ;    return desHost;}intUdpStack::getSocketFD (){    assert(data);    return data->socketFd;}voidUdpStack::addToFdSet ( fd_set* set ){    assert(set);    FD_SET(data->socketFd, set);}intUdpStack::getMaxFD ( int prevMax ){    return ( getSocketFD() > prevMax ) ? getSocketFD() : prevMax;}boolUdpStack::checkIfSet ( fd_set* set ){    assert(set);    return ( FD_ISSET(data->socketFd, set) ? true : false );}intUdpStack::receive ( const char* buf, const int bufSize ){    if ((mode == sendonly) || (mode == inactive))    {        cpLog(LOG_ERR, "The stack is not in a state capable of receiving.");        return -1;    }    int len = recv( data->socketFd,                    (char *)buf, bufSize,                    0 /*flags */);    if ( len < 0 )    {        int err = errno;	cpLog(LOG_ERR, "UdpStack: receive error: %s", strerror(err));#if 0        throw UdpStackException(errMsg.str());        assert(0);#endif        //        cpLog(LOG_DEBUG_STACK, "UdpStack::receive pkt len=0");    }    else if (len == 0)    {	// received no bytes	cpLog(LOG_DEBUG, "did not receive any data");    }    else    {        numBytesReceived += len;        numPacketsReceived += 1;    }    if ( (logFlag) && (len > 0) )    {        strstream lenln1;        lenln1 << ++rcvCount << " " << len << "\n" << char(0);        in_log->write(lenln1.str(), strlen(lenln1.str()));        in_log->write(buf, len);        in_log->write(separator, 6);        lenln1.freeze(false);    }    return len;}intUdpStack::receiveFrom ( const char* buffer,                        const int bufSize,                        NetworkAddress* sender ) // returns bytes read{    if ((mode == sendonly) || (mode == inactive))    {        cpLog(LOG_ERR, "The stack is not capable to receive. ");        return -1;    }    struct sockaddr_storage xSrc;    int srcLen = sizeof(xSrc);    if(sender) sender->getSockAddr(&xSrc);#if defined(WIN32)    /* WSAECONNRESET (10054) Connection reset by peer.     * A existing connection was forcibly closed by the remote host. This     * normally results if the peer application on the remote host is suddenly     * stopped, the host is rebooted, or the remote host used a "hard close" (see     * setsockopt for more information on the SO_LINGER option on the remote     * socket.) This error may also result if a connection was broken due to     * "keep-alive" activity detecting a failure while one or more operations are     * in progress. Operations that were in progress fail with WSAENETRESET.     * Subsequent operations fail with WSAECONNRESET. Fix suggested by Alexandr Kuzmin gin@nnov.stelt.ru.     */    int len = 0;    do    {        len = recvfrom( data->socketFd,                            (char *)buffer,                            bufSize,                            0 /*flags */ ,                            (sockaddr*) &xSrc,                            (socklen_t*) &srcLen);    } while( (len == -1) && (WSAGetLastError() == WSAECONNRESET ) );#else    int len = 0;    bool ipV6 = false;    struct in6_pktinfo pktinfo;    if(NetworkConfig::instance().getAddrFamily() == AF_INET)    {        len = recvfrom( data->socketFd,                        (char *)buffer,                        bufSize,                        0 /*flags */ ,                        (struct sockaddr*) &xSrc,                        (socklen_t*) &srcLen);    }    else    {        ipV6 = true;        int flags=0;        len = recvfrom_flags( data->socketFd,                        (char *)buffer,                        bufSize,                        &flags /*flags */ ,                        (struct sockaddr*) &xSrc,                        (socklen_t*) &srcLen,                        &pktinfo);    }#endif    if ( len <= 0 )    {        int err = errno;        strstream errMsg;        errMsg << "UdpStack<" << getLclName() << ">::receive error : ";        errMsg << strerror(err);        errMsg << char(0);        cpLog(LOG_ERR, "%s", errMsg.str());        errMsg.freeze(false);    }    else    {        if(sender)        {            struct sockaddr_storage xSrcT;	    sender->getSockAddr(&xSrcT);            if(memcmp(&xSrc, &xSrcT, srcLen)  == 0)	    {		//No need to set anything, return                numBytesReceived += len;                numPacketsReceived += 1;		return len;	    }            //Do the heavy-weight work only if the caller shows interest	    char hostname[256];	    char port[64];            hostname[0] = '\0';            port[0] = '\0';	    int err = getnameinfo((struct sockaddr *)&xSrc, srcLen, hostname, 256, port, 64, NI_NUMERICHOST | NI_NUMERICSERV);	    if (err) {                cpLog(LOG_ERR, "Failed to get the host name");	    }            string tmp = hostname;            if(ipV6)            {                struct sockaddr_in6* sin6 = (struct sockaddr_in6*)&xSrc;                if(IN6_IS_ADDR_LOOPBACK((struct in6_addr*)&sin6->sin6_addr) &&                   (inet_ntop(AF_INET6, &pktinfo.ipi6_addr, hostname, 256)))                {	            tmp = "[";	            tmp += hostname;	            tmp += "]";                }                else                {	            tmp = "[";	            tmp += hostname;	            tmp += "]";                }            }            cpLog(LOG_DEBUG, "***Received from:%s:%s", tmp.c_str(), port);            sender->setPort(atoi(port));            if((sender->getIpName() != Data(hostname)))            {                sender->setHostName(tmp.c_str());            }        }        numBytesReceived += len;        numPacketsReceived += 1;    }    if ( (logFlag) && (len > 0) )    {        strstream lenln2;        lenln2 << ++rcvCount << " " << len << "\n" << char(0);        in_log->write(lenln2.str(), strlen(lenln2.str()));        in_log->write(buffer, len);        in_log->write(separator, 6);        lenln2.freeze(false);    }    return len;}intUdpStack::receiveTimeout ( const char* buffer,                           const int bufSize,                           NetworkAddress* sender,                           int sec,                           int usec){#ifndef __vxworks    timeval tv;    fd_set rset;    int fd = getSocketFD();// Make the coket non-blocking and then change it againb after the receivfrom#ifndef WIN32    int retVal;    bool madeNonBlocking = false;    if(blockingFlg)    {        madeNonBlocking = true;        if(setModeBlocking(false) < 0)            return -1;    }#else    int retVal;    unsigned long non_blocking = 1;    if (ioctlsocket(fd, FIONBIO, &non_blocking))        return -1;#endif    // select will return upon timeout, error or received message    FD_ZERO(&rset);    FD_SET(fd, &rset);    tv.tv_sec = sec;    tv.tv_usec = usec;    retVal = select(fd + 1, &rset, NULL, NULL, &tv);    // we don't care about no stinking error    if (retVal <= 0)        return retVal;    retVal = receiveFrom( buffer,                          bufSize,                          sender);#ifndef WIN32    if(madeNonBlocking)    {        if(setModeBlocking(true) < 0);            return -1;    }#else	non_blocking = 0;	if (ioctlsocket(fd, FIONBIO, &non_blocking) != 0)	return -1;#endif    return retVal;#else    cpLog(LOG_ERR, "UdpStack::receiveTimeout  * not defined in vxworks *\n");    return -1;#endif}// uses send() which is better to get ICMP msg back// function returns a 0  normallyvoidUdpStack::transmit ( const char* buf, const int length ){    if ((mode == recvonly) || (mode == inactive))    {        cpLog(LOG_ERR, "The stack is not capable to transmit. ");        return ;    }    assert(buf);    assert(length > 0);    if ( packetLossProbability > 0.0 )    {        static bool randInit = false;        if (!randInit)        {            randInit = true;            timeval tv;            gettimeofday(&tv, NULL);            long seed = tv.tv_sec + tv.tv_usec;            srandom(seed);        }        double numerator( random() & 0x7FFFFFFF );        double denominator( 0x7FFFFFFF );        double prob = numerator / denominator;        if ( prob < packetLossProbability )        {            // ok - just drop this packet            return ;        }    }    int count = send( data->socketFd,                      (char *)buf, length,                      0 /* flags */ );    if ( count < 0 )    {        int err = errno;        strstream errMsg;        errMsg << "UdpStack<" << getRmtName() << ">::transmit ";        switch (err)        {            case ECONNREFUSED:            {                // This is the most common error - you get it if the host                // does not exist or is nor running a program to recevice                // the packets. This is what you get with the other side                // crashes.                errMsg << "Connection refused by destination host";                errMsg << char(0);                cpLog(LOG_ERR, errMsg.str());#if 0                throw UdpStackExceptionConectionRefused(errMsg.str());#endif            }            break;            case EHOSTDOWN:            {                errMsg << "destination host is down";                errMsg << char(0);                cpLog(LOG_ERR, errMsg.str());            }            break;            case EHOSTUNREACH:            {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -