annotate core/UdpServer.cpp @ 124:23137a333c93 scope-refactoring

Implemented destructor of UdpServer which closes the socket
author Giulio Moro <giuliomoro@yahoo.it>
date Sat, 22 Aug 2015 02:51:39 +0100
parents 2197435e8fb4
children 719119fb2905
rev   line source
giuliomoro@44 1 /*
giuliomoro@44 2 * udpServer.cpp
giuliomoro@44 3 *
giuliomoro@44 4 * Created on: 19 May 2015
giuliomoro@44 5 * Author: giulio moro
giuliomoro@44 6 */
giuliomoro@44 7 #include "../include/UdpServer.h"
giuliomoro@44 8
giuliomoro@44 9 UdpServer::UdpServer(int aPort){
giuliomoro@44 10 init(aPort);
giuliomoro@44 11 };
giuliomoro@44 12 UdpServer::UdpServer(){
giuliomoro@44 13 init(0);
giuliomoro@44 14 }
giuliomoro@44 15 UdpServer::~UdpServer(){
giuliomoro@124 16 printf("Close the socket\n");
giuliomoro@124 17 shutdown(inSocket, 0); //Stop receiving data for this socket. If further data arrives, reject it.
giuliomoro@54 18 //TODO: unbind from port. AFAIK, this involves closing the socket, therefore creating the socket should become part of bindToPort
giuliomoro@44 19 };
giuliomoro@44 20 bool UdpServer::init(int aPort){
giuliomoro@44 21 enabled=true;
giuliomoro@121 22 stZeroTimeOut.tv_sec = 0; //set timeout to 0
giuliomoro@121 23 stZeroTimeOut.tv_usec = 0;
giuliomoro@44 24 inSocket=socket(AF_INET, SOCK_DGRAM, 0);
giuliomoro@44 25 if (inSocket < 0){
giuliomoro@44 26 enabled=false;
giuliomoro@44 27 }
giuliomoro@44 28 length = sizeof(server);
giuliomoro@44 29 server.sin_family=AF_INET;
giuliomoro@44 30 server.sin_addr.s_addr=INADDR_ANY;
giuliomoro@44 31 enabled=bindToPort(aPort);
giuliomoro@44 32 wasteBufferSize=2048;
giuliomoro@44 33 wasteBuffer=malloc(wasteBufferSize);
giuliomoro@44 34 return enabled;
giuliomoro@44 35 }
giuliomoro@44 36
giuliomoro@44 37 bool UdpServer::bindToPort(int aPort){
giuliomoro@44 38 port=aPort;
giuliomoro@53 39 if(port<1){
giuliomoro@53 40 enabled=false;
giuliomoro@53 41 return false;
giuliomoro@53 42 }
giuliomoro@44 43 server.sin_port=htons(port);
giuliomoro@44 44 if (bind(inSocket,(struct sockaddr *)&server,length)<0){
giuliomoro@44 45 enabled=false;
giuliomoro@44 46 return false;
giuliomoro@44 47 }
giuliomoro@53 48 enabled=true;
giuliomoro@44 49 return true;
giuliomoro@44 50 };
giuliomoro@121 51 int UdpServer::waitUntilReady(bool readyForReading, int timeoutMsecs){
giuliomoro@121 52 // 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 53 if(enabled==false)
giuliomoro@121 54 return -1;
giuliomoro@121 55 if(timeoutMsecs<0)
giuliomoro@121 56 return select(inSocket+1, &stReadFDS, NULL, NULL, NULL); //calling this with a NULL timeout will block indefinitely
giuliomoro@121 57 FD_ZERO(&stReadFDS);
giuliomoro@121 58 FD_SET(inSocket, &stReadFDS);
giuliomoro@121 59 if(timeoutMsecs>=1000){
giuliomoro@121 60 float timeOutSecs=timeoutMsecs*0.001;
giuliomoro@121 61 stTimeOut.tv_sec=(long int)timeOutSecs;
giuliomoro@121 62 timeOutSecs-=(int)timeOutSecs;
giuliomoro@121 63 stTimeOut.tv_usec=(long int)(timeOutSecs*1000000);
giuliomoro@121 64 } else //faster!
giuliomoro@121 65 stTimeOut.tv_usec=(long int)timeoutMsecs*1000;
giuliomoro@121 66 int descriptorReady= select(inSocket+1, &stReadFDS, NULL, NULL, &stTimeOut);
giuliomoro@121 67 return descriptorReady>0? 1 : descriptorReady;
giuliomoro@121 68 }
giuliomoro@121 69
giuliomoro@44 70 int UdpServer::read(//Returns the number of bytes read, or -1 if there was an error.
giuliomoro@44 71 void *destBuffer,
giuliomoro@121 72 int maxBytesToRead,
giuliomoro@121 73 bool blockUntilSpecifiedAmountHasArrived)
giuliomoro@121 74 {
giuliomoro@44 75 if(enabled==false)
giuliomoro@44 76 return -1;
giuliomoro@44 77 FD_ZERO(&stReadFDS);
giuliomoro@44 78 FD_SET(inSocket, &stReadFDS);
giuliomoro@121 79 int descriptorReady= select(inSocket+1, &stReadFDS, NULL, NULL, &stZeroTimeOut);
giuliomoro@44 80 if(descriptorReady<0){ //an error occurred
giuliomoro@44 81 return -1;
giuliomoro@44 82 }
giuliomoro@44 83 int numberOfBytes=0;
giuliomoro@121 84 // do
giuliomoro@121 85 {
giuliomoro@121 86 if (FD_ISSET(inSocket, &stReadFDS))
giuliomoro@121 87 {
giuliomoro@121 88 // numberOfBytes=recvfrom(inSocket,destBuffer,maxBytesToRead,0,(struct sockaddr *)&from,&fromLength);
giuliomoro@121 89 numberOfBytes+=recv(inSocket,destBuffer,maxBytesToRead-numberOfBytes,0);
giuliomoro@121 90 if(numberOfBytes<0)
giuliomoro@121 91 return -1;
giuliomoro@121 92 }
giuliomoro@44 93 }
giuliomoro@121 94 // while (blockUntilSpecifiedAmountHasArrived && numberOfBytes==maxBytesToRead);
giuliomoro@44 95 return numberOfBytes;
giuliomoro@121 96 }
giuliomoro@44 97 int UdpServer::emptySocket(){
giuliomoro@44 98 return emptySocket(0);
giuliomoro@44 99 }
giuliomoro@44 100 int UdpServer::emptySocket(int maxBytes){//discards up to maxBytes from the socket. Returns the number of bytes discarded.
giuliomoro@44 101 if(wasteBuffer==NULL)
giuliomoro@44 102 return -1;
giuliomoro@44 103 int numberOfBytes=0;
giuliomoro@121 104 while(int n=read(wasteBuffer, wasteBufferSize, false)){// calls the read function until it does not return any more bytes (i.e.: socket is empty)
giuliomoro@44 105 if(n>0)
giuliomoro@44 106 numberOfBytes+=n;
giuliomoro@44 107 if(n<0)
giuliomoro@44 108 return -1;
giuliomoro@44 109 if(maxBytes>0 && numberOfBytes>=maxBytes)
giuliomoro@44 110 break;
giuliomoro@44 111 };
giuliomoro@44 112 return numberOfBytes;
giuliomoro@44 113 }
giuliomoro@44 114 void* UdpServer::getWaste(){ //returns the last datagram retrieved by emptySocket()
giuliomoro@44 115 return wasteBuffer;
giuliomoro@44 116 }
giuliomoro@44 117