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