giuliomoro@44: /* giuliomoro@44: * udpServer.cpp giuliomoro@44: * giuliomoro@44: * Created on: 19 May 2015 giuliomoro@44: * Author: giulio moro giuliomoro@44: */ giuliomoro@135: #include "UdpServer.h" giuliomoro@44: giuliomoro@44: UdpServer::UdpServer(int aPort){ giuliomoro@44: init(aPort); giuliomoro@44: }; giuliomoro@44: UdpServer::UdpServer(){ giuliomoro@44: init(0); giuliomoro@44: } giuliomoro@44: UdpServer::~UdpServer(){ giuliomoro@126: close(); giuliomoro@44: }; giuliomoro@44: bool UdpServer::init(int aPort){ giuliomoro@44: enabled=true; giuliomoro@121: stZeroTimeOut.tv_sec = 0; //set timeout to 0 giuliomoro@121: stZeroTimeOut.tv_usec = 0; giuliomoro@44: inSocket=socket(AF_INET, SOCK_DGRAM, 0); giuliomoro@44: if (inSocket < 0){ giuliomoro@44: enabled=false; giuliomoro@44: } giuliomoro@44: length = sizeof(server); giuliomoro@44: server.sin_family=AF_INET; giuliomoro@44: server.sin_addr.s_addr=INADDR_ANY; giuliomoro@44: enabled=bindToPort(aPort); giuliomoro@44: wasteBufferSize=2048; giuliomoro@44: wasteBuffer=malloc(wasteBufferSize); giuliomoro@135: memset(&stTimeOut,0,sizeof(struct timeval)); giuliomoro@44: return enabled; giuliomoro@44: } giuliomoro@44: giuliomoro@44: bool UdpServer::bindToPort(int aPort){ giuliomoro@44: port=aPort; giuliomoro@53: if(port<1){ giuliomoro@53: enabled=false; giuliomoro@53: return false; giuliomoro@53: } giuliomoro@44: server.sin_port=htons(port); giuliomoro@44: if (bind(inSocket,(struct sockaddr *)&server,length)<0){ giuliomoro@44: enabled=false; giuliomoro@44: return false; giuliomoro@44: } giuliomoro@53: enabled=true; giuliomoro@44: return true; giuliomoro@126: } giuliomoro@126: giuliomoro@126: void UdpServer::close(){ giuliomoro@126: int ret=::close(inSocket); giuliomoro@126: if(ret != 0) giuliomoro@126: printf("Error while closing socket, errno: %d\n", errno);//Stop receiving data for this socket. If further data arrives, reject it. giuliomoro@126: inSocket=0; giuliomoro@126: } giuliomoro@126: giuliomoro@121: int UdpServer::waitUntilReady(bool readyForReading, int timeoutMsecs){ giuliomoro@121: // If the socket is ready on return, this returns 1. If it times-out before the socket becomes ready, it returns 0. If an error occurs, it returns -1. giuliomoro@121: if(enabled==false) giuliomoro@121: return -1; giuliomoro@121: if(timeoutMsecs<0) giuliomoro@121: return select(inSocket+1, &stReadFDS, NULL, NULL, NULL); //calling this with a NULL timeout will block indefinitely giuliomoro@121: FD_ZERO(&stReadFDS); giuliomoro@121: FD_SET(inSocket, &stReadFDS); giuliomoro@121: if(timeoutMsecs>=1000){ giuliomoro@121: float timeOutSecs=timeoutMsecs*0.001; giuliomoro@121: stTimeOut.tv_sec=(long int)timeOutSecs; giuliomoro@121: timeOutSecs-=(int)timeOutSecs; giuliomoro@121: stTimeOut.tv_usec=(long int)(timeOutSecs*1000000); giuliomoro@121: } else //faster! giuliomoro@121: stTimeOut.tv_usec=(long int)timeoutMsecs*1000; giuliomoro@121: int descriptorReady= select(inSocket+1, &stReadFDS, NULL, NULL, &stTimeOut); giuliomoro@121: return descriptorReady>0? 1 : descriptorReady; giuliomoro@121: } giuliomoro@121: giuliomoro@44: int UdpServer::read(//Returns the number of bytes read, or -1 if there was an error. giuliomoro@44: void *destBuffer, giuliomoro@121: int maxBytesToRead, giuliomoro@121: bool blockUntilSpecifiedAmountHasArrived) giuliomoro@121: { giuliomoro@44: if(enabled==false) giuliomoro@44: return -1; giuliomoro@44: FD_ZERO(&stReadFDS); giuliomoro@44: FD_SET(inSocket, &stReadFDS); giuliomoro@131: int descriptorReady= select(inSocket+1, &stReadFDS, NULL, NULL, &stZeroTimeOut); //TODO: this is not JUCE-compliant giuliomoro@44: if(descriptorReady<0){ //an error occurred giuliomoro@44: return -1; giuliomoro@44: } giuliomoro@44: int numberOfBytes=0; giuliomoro@121: // do giuliomoro@121: { giuliomoro@121: if (FD_ISSET(inSocket, &stReadFDS)) giuliomoro@121: { giuliomoro@121: // numberOfBytes=recvfrom(inSocket,destBuffer,maxBytesToRead,0,(struct sockaddr *)&from,&fromLength); giuliomoro@121: numberOfBytes+=recv(inSocket,destBuffer,maxBytesToRead-numberOfBytes,0); giuliomoro@121: if(numberOfBytes<0) giuliomoro@121: return -1; giuliomoro@121: } giuliomoro@44: } giuliomoro@121: // while (blockUntilSpecifiedAmountHasArrived && numberOfBytes==maxBytesToRead); giuliomoro@44: return numberOfBytes; giuliomoro@121: } giuliomoro@131: int UdpServer::empty(){ giuliomoro@131: return empty(0); giuliomoro@44: } giuliomoro@131: int UdpServer::empty(int maxCount){ giuliomoro@131: int count=0; giuliomoro@131: int n; giuliomoro@131: do { giuliomoro@131: if(waitUntilReady(true, 0)==0) giuliomoro@131: return 0; giuliomoro@131: float waste; giuliomoro@131: n=read(&waste, sizeof(float), false); giuliomoro@131: count++; giuliomoro@131: } while (n>0 && (maxCount<=0 || maxCount