giuliomoro@217
|
1 /*
|
giuliomoro@217
|
2 * udpServer.cpp
|
giuliomoro@217
|
3 *
|
giuliomoro@217
|
4 * Created on: 19 May 2015
|
giuliomoro@217
|
5 * Author: giulio moro
|
giuliomoro@217
|
6 */
|
giuliomoro@217
|
7 #include "UdpServer.h"
|
giuliomoro@217
|
8
|
giuliomoro@217
|
9 UdpServer::UdpServer(int aPort){
|
giuliomoro@217
|
10 init(aPort);
|
giuliomoro@217
|
11 };
|
giuliomoro@217
|
12 UdpServer::UdpServer(){
|
giuliomoro@217
|
13 init(0);
|
giuliomoro@217
|
14 }
|
giuliomoro@217
|
15 UdpServer::~UdpServer(){
|
giuliomoro@217
|
16 close();
|
giuliomoro@217
|
17 };
|
giuliomoro@217
|
18 bool UdpServer::init(int aPort){
|
giuliomoro@217
|
19 enabled=true;
|
giuliomoro@217
|
20 stZeroTimeOut.tv_sec = 0; //set timeout to 0
|
giuliomoro@217
|
21 stZeroTimeOut.tv_usec = 0;
|
giuliomoro@217
|
22 inSocket=socket(AF_INET, SOCK_DGRAM, 0);
|
giuliomoro@217
|
23 if (inSocket < 0){
|
giuliomoro@217
|
24 enabled=false;
|
giuliomoro@217
|
25 }
|
giuliomoro@217
|
26 length = sizeof(server);
|
giuliomoro@217
|
27 server.sin_family=AF_INET;
|
giuliomoro@217
|
28 server.sin_addr.s_addr=INADDR_ANY;
|
giuliomoro@217
|
29 enabled=bindToPort(aPort);
|
giuliomoro@217
|
30 wasteBufferSize=2048;
|
giuliomoro@217
|
31 wasteBuffer=malloc(wasteBufferSize);
|
giuliomoro@217
|
32 memset(&stTimeOut,0,sizeof(struct timeval));
|
giuliomoro@217
|
33 return enabled;
|
giuliomoro@217
|
34 }
|
giuliomoro@217
|
35
|
giuliomoro@217
|
36 bool UdpServer::bindToPort(int aPort){
|
giuliomoro@217
|
37 port=aPort;
|
giuliomoro@217
|
38 if(port<1){
|
giuliomoro@217
|
39 enabled=false;
|
giuliomoro@217
|
40 return false;
|
giuliomoro@217
|
41 }
|
giuliomoro@217
|
42 server.sin_port=htons(port);
|
giuliomoro@217
|
43 if (bind(inSocket,(struct sockaddr *)&server,length)<0){
|
giuliomoro@217
|
44 enabled=false;
|
giuliomoro@217
|
45 return false;
|
giuliomoro@217
|
46 }
|
giuliomoro@217
|
47 enabled=true;
|
giuliomoro@217
|
48 return true;
|
giuliomoro@217
|
49 }
|
giuliomoro@217
|
50
|
giuliomoro@217
|
51 void UdpServer::close(){
|
giuliomoro@217
|
52 int ret=::close(inSocket);
|
giuliomoro@217
|
53 if(ret != 0)
|
giuliomoro@217
|
54 printf("Error while closing socket, errno: %d\n", errno);//Stop receiving data for this socket. If further data arrives, reject it.
|
giuliomoro@217
|
55 inSocket=0;
|
giuliomoro@217
|
56 }
|
giuliomoro@217
|
57
|
giuliomoro@217
|
58 int UdpServer::waitUntilReady(bool readyForReading, int timeoutMsecs){
|
giuliomoro@217
|
59 // 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
|
60 if(enabled==false)
|
giuliomoro@217
|
61 return -1;
|
giuliomoro@217
|
62 if(timeoutMsecs<0)
|
giuliomoro@217
|
63 return select(inSocket+1, &stReadFDS, NULL, NULL, NULL); //calling this with a NULL timeout will block indefinitely
|
giuliomoro@217
|
64 FD_ZERO(&stReadFDS);
|
giuliomoro@217
|
65 FD_SET(inSocket, &stReadFDS);
|
giuliomoro@217
|
66 float timeOutSecs=timeoutMsecs*0.001;
|
giuliomoro@217
|
67 stTimeOut.tv_sec=(long int)timeOutSecs;
|
giuliomoro@217
|
68 timeOutSecs-=(int)timeOutSecs;
|
giuliomoro@217
|
69 long int timeOutUsecs=timeOutSecs*1000000;
|
giuliomoro@217
|
70 stTimeOut.tv_usec=timeOutUsecs;
|
giuliomoro@217
|
71 int descriptorReady= select(inSocket+1, &stReadFDS, NULL, NULL, &stTimeOut);
|
giuliomoro@217
|
72 // printf("stTimeOut.tv_sec=%ld, stTimeOut.tv_usec=%ld, descriptorReady: \n",stTimeOut.tv_sec,stTimeOut.tv_usec, descriptorReady);
|
giuliomoro@217
|
73 // return descriptorReady>0 ? (timeOutUsecs-stTimeOut.tv_usec) : descriptorReady;
|
giuliomoro@217
|
74 return descriptorReady>0 ? 1 : descriptorReady;
|
giuliomoro@217
|
75 }
|
giuliomoro@217
|
76
|
giuliomoro@217
|
77 int UdpServer::read(//Returns the number of bytes read, or -1 if there was an error.
|
giuliomoro@217
|
78 void *destBuffer,
|
giuliomoro@217
|
79 int maxBytesToRead,
|
giuliomoro@217
|
80 bool blockUntilSpecifiedAmountHasArrived)
|
giuliomoro@217
|
81 {
|
giuliomoro@217
|
82 if(enabled==false)
|
giuliomoro@217
|
83 return -1;
|
giuliomoro@217
|
84 FD_ZERO(&stReadFDS);
|
giuliomoro@217
|
85 FD_SET(inSocket, &stReadFDS);
|
giuliomoro@217
|
86 int descriptorReady= select(inSocket+1, &stReadFDS, NULL, NULL, &stZeroTimeOut); //TODO: this is not JUCE-compliant
|
giuliomoro@217
|
87 if(descriptorReady<0){ //an error occurred
|
giuliomoro@217
|
88 return -1;
|
giuliomoro@217
|
89 }
|
giuliomoro@217
|
90 int numberOfBytes=0;
|
giuliomoro@217
|
91 // do
|
giuliomoro@217
|
92 {
|
giuliomoro@217
|
93 if (FD_ISSET(inSocket, &stReadFDS))
|
giuliomoro@217
|
94 {
|
giuliomoro@217
|
95 // numberOfBytes=recvfrom(inSocket,destBuffer,maxBytesToRead,0,(struct sockaddr *)&from,&fromLength);
|
giuliomoro@217
|
96 numberOfBytes+=recv(inSocket,destBuffer,maxBytesToRead-numberOfBytes,0);
|
giuliomoro@217
|
97 if(numberOfBytes<0)
|
giuliomoro@217
|
98 return -1;
|
giuliomoro@217
|
99 }
|
giuliomoro@217
|
100 }
|
giuliomoro@217
|
101 // while (blockUntilSpecifiedAmountHasArrived && numberOfBytes==maxBytesToRead);
|
giuliomoro@217
|
102 return numberOfBytes;
|
giuliomoro@217
|
103 }
|
giuliomoro@217
|
104 int UdpServer::empty(){
|
giuliomoro@217
|
105 return empty(0);
|
giuliomoro@217
|
106 }
|
giuliomoro@217
|
107 int UdpServer::empty(int maxCount){
|
giuliomoro@217
|
108 int count=0;
|
giuliomoro@217
|
109 int n;
|
giuliomoro@217
|
110 do {
|
giuliomoro@217
|
111 if(waitUntilReady(true, 0)==0)
|
giuliomoro@217
|
112 return 0;
|
giuliomoro@217
|
113 float waste;
|
giuliomoro@217
|
114 n=read(&waste, sizeof(float), false);
|
giuliomoro@217
|
115 count++;
|
giuliomoro@217
|
116 } while (n>0 && (maxCount<=0 || maxCount<count));
|
giuliomoro@217
|
117 printf("socket emptied with %d reads\n", count);
|
giuliomoro@217
|
118 return count;
|
giuliomoro@217
|
119 }
|