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