19,519
社区成员




#define RTPIOCTL ioctlsocket
unsigned long len;
len = 0;
RTPIOCTL(sock,FIONREAD,&len);
if (len <= 0)
return 0;
int RTPUDPv4Transmitter::Create(size_t maximumpacketsize,const RTPTransmissionParams *transparams)
{
const RTPUDPv4TransmissionParams *params,defaultparams;
struct sockaddr_in addr;
RTPSOCKLENTYPE size;
int status;
if (!init)
return ERR_RTP_UDPV4TRANS_NOTINIT;
MAINMUTEX_LOCK
if (created)
{
MAINMUTEX_UNLOCK
return ERR_RTP_UDPV4TRANS_ALREADYCREATED;
}
// Obtain transmission parameters
if (transparams == 0)
params = &defaultparams;
else
{
if (transparams->GetTransmissionProtocol() != RTPTransmitter::IPv4UDPProto)
{
MAINMUTEX_UNLOCK
return ERR_RTP_UDPV4TRANS_ILLEGALPARAMETERS;
}
params = (const RTPUDPv4TransmissionParams *)transparams;
}
// Check if portbase is even
if (params->GetPortbase()%2 != 0)
{
MAINMUTEX_UNLOCK
return ERR_RTP_UDPV4TRANS_PORTBASENOTEVEN;
}
// create sockets
rtpsock = socket(PF_INET,SOCK_DGRAM,0); // Leo IPPROTO_IP
if (rtpsock == RTPSOCKERR)
{
MAINMUTEX_UNLOCK
return ERR_RTP_UDPV4TRANS_CANTCREATESOCKET;
}
rtcpsock = socket(PF_INET,SOCK_DGRAM,0);
if (rtcpsock == RTPSOCKERR)
{
RTPCLOSE(rtpsock);
MAINMUTEX_UNLOCK
return ERR_RTP_UDPV4TRANS_CANTCREATESOCKET;
}
// set socket buffer sizes
size = params->GetRTPReceiveBuffer();
if (setsockopt(rtpsock,SOL_SOCKET,SO_RCVBUF,(const char *)&size,sizeof(int)) != 0)
{
RTPCLOSE(rtpsock);
RTPCLOSE(rtcpsock);
MAINMUTEX_UNLOCK
return ERR_RTP_UDPV4TRANS_CANTSETRTPRECEIVEBUF;
}
size = params->GetRTPSendBuffer();
if (setsockopt(rtpsock,SOL_SOCKET,SO_SNDBUF,(const char *)&size,sizeof(int)) != 0)
{
RTPCLOSE(rtpsock);
RTPCLOSE(rtcpsock);
MAINMUTEX_UNLOCK
return ERR_RTP_UDPV4TRANS_CANTSETRTPTRANSMITBUF;
}
size = params->GetRTCPReceiveBuffer();
if (setsockopt(rtcpsock,SOL_SOCKET,SO_RCVBUF,(const char *)&size,sizeof(int)) != 0)
{
RTPCLOSE(rtpsock);
RTPCLOSE(rtcpsock);
MAINMUTEX_UNLOCK
return ERR_RTP_UDPV4TRANS_CANTSETRTCPRECEIVEBUF;
}
size = params->GetRTCPSendBuffer();
if (setsockopt(rtcpsock,SOL_SOCKET,SO_SNDBUF,(const char *)&size,sizeof(int)) != 0)
{
RTPCLOSE(rtpsock);
RTPCLOSE(rtcpsock);
MAINMUTEX_UNLOCK
return ERR_RTP_UDPV4TRANS_CANTSETRTCPTRANSMITBUF;
}
// bind sockets
bindIP = params->GetBindIP();
mcastifaceIP = params->GetMulticastInterfaceIP();
memset(&addr,0,sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons(params->GetPortbase());
addr.sin_addr.s_addr = htonl(bindIP); // Leo htonl(INADDR_ANY);
if (bind(rtpsock,(struct sockaddr *)&addr,sizeof(struct sockaddr_in)) != 0)
{
RTPCLOSE(rtpsock);
RTPCLOSE(rtcpsock);
MAINMUTEX_UNLOCK
return ERR_RTP_UDPV4TRANS_CANTBINDRTPSOCKET;
}
memset(&addr,0,sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons(params->GetPortbase()+1);
addr.sin_addr.s_addr = htonl(bindIP);
if (bind(rtcpsock,(struct sockaddr *)&addr,sizeof(struct sockaddr_in)) != 0)
{
RTPCLOSE(rtpsock);
RTPCLOSE(rtcpsock);
MAINMUTEX_UNLOCK
return ERR_RTP_UDPV4TRANS_CANTBINDRTCPSOCKET;
}
// Try to obtain local IP addresses
localIPs = params->GetLocalIPList();
if (localIPs.empty()) // User did not provide list of local IP addresses, calculate them
{
int status;
if ((status = CreateLocalIPList()) < 0)
{
RTPCLOSE(rtpsock);
RTPCLOSE(rtcpsock);
MAINMUTEX_UNLOCK
return status;
}
#ifdef RTPDEBUG
std::cout << "Found these local IP addresses:" << std::endl;
std::list<uint32_t>::const_iterator it;
for (it = localIPs.begin() ; it != localIPs.end() ; it++)
{
RTPIPv4Address a(*it);
std::cout << a.GetAddressString() << std::endl;
}
#endif // RTPDEBUG
}
#ifdef RTP_SUPPORT_IPV4MULTICAST
if (SetMulticastTTL(params->GetMulticastTTL()))
supportsmulticasting = true;
else
supportsmulticasting = false;
#else // no multicast support enabled
supportsmulticasting = false;
#endif // RTP_SUPPORT_IPV4MULTICAST
if ((status = CreateAbortDescriptors()) < 0)
{
RTPCLOSE(rtpsock);
RTPCLOSE(rtcpsock);
MAINMUTEX_UNLOCK
return status;
}
if (maximumpacketsize > RTPUDPV4TRANS_MAXPACKSIZE)
{
RTPCLOSE(rtpsock);
RTPCLOSE(rtcpsock);
DestroyAbortDescriptors();
MAINMUTEX_UNLOCK
return ERR_RTP_UDPV4TRANS_SPECIFIEDSIZETOOBIG;
}
maxpacksize = maximumpacketsize;
portbase = params->GetPortbase();
multicastTTL = params->GetMulticastTTL();
receivemode = RTPTransmitter::AcceptAll;
localhostname = 0;
localhostnamelength = 0;
waitingfordata = false;
created = true;
MAINMUTEX_UNLOCK
return 0;
}
int RTPUDPv4Transmitter::PollSocket(bool rtp)
{
RTPSOCKLENTYPE fromlen;
int recvlen;
char packetbuffer[RTPUDPV4TRANS_MAXPACKSIZE];
#if (defined(WIN32) || defined(_WIN32_WCE))
SOCKET sock;
unsigned long len;
#else
size_t len;
int sock;
#endif // WIN32
struct sockaddr_in srcaddr;
if (rtp)
sock = rtpsock;
else
sock = rtcpsock;
len = 0;
RTPIOCTL(sock,FIONREAD,&len); // 此句出错
if (len <= 0)
return 0;
while (len > 0)
{
RTPTime curtime = RTPTime::CurrentTime();
fromlen = sizeof(struct sockaddr_in);
recvlen = recvfrom(sock,packetbuffer,RTPUDPV4TRANS_MAXPACKSIZE,0,(struct sockaddr *)&srcaddr,&fromlen);
if (recvlen > 0)
{
bool acceptdata;
// got data, process it
if (receivemode == RTPTransmitter::AcceptAll)
acceptdata = true;
else
acceptdata = ShouldAcceptData(ntohl(srcaddr.sin_addr.s_addr),ntohs(srcaddr.sin_port));
if (acceptdata)
{
RTPRawPacket *pack;
RTPIPv4Address *addr;
uint8_t *datacopy;
addr = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPADDRESS) RTPIPv4Address(ntohl(srcaddr.sin_addr.s_addr),ntohs(srcaddr.sin_port));
if (addr == 0)
return ERR_RTP_OUTOFMEM;
datacopy = RTPNew(GetMemoryManager(),(rtp)?RTPMEM_TYPE_BUFFER_RECEIVEDRTPPACKET:RTPMEM_TYPE_BUFFER_RECEIVEDRTCPPACKET) uint8_t[recvlen];
if (datacopy == 0)
{
RTPDelete(addr,GetMemoryManager());
return ERR_RTP_OUTOFMEM;
}
memcpy(datacopy,packetbuffer,recvlen);
pack = RTPNew(GetMemoryManager(),RTPMEM_TYPE_CLASS_RTPRAWPACKET) RTPRawPacket(datacopy,recvlen,addr,curtime,rtp,GetMemoryManager());
if (pack == 0)
{
RTPDelete(addr,GetMemoryManager());
RTPDeleteByteArray(datacopy,GetMemoryManager());
return ERR_RTP_OUTOFMEM;
}
rawpacketlist.push_back(pack);
}
}
len = 0;
RTPIOCTL(sock,FIONREAD,&len);
}
return 0;
}