changeset 213:c083217c4195 robbie

Got UdpServer from ClockSync
author Giulio Moro <giuliomoro@yahoo.it>
date Tue, 09 Feb 2016 15:52:35 +0000
parents 301dceb39ec8
children
files core/UdpServer.cpp include/UdpServer.h
diffstat 2 files changed, 189 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/UdpServer.cpp	Tue Feb 09 15:52:35 2016 +0000
@@ -0,0 +1,119 @@
+/*
+ * udpServer.cpp
+ *
+ *  Created on: 19 May 2015
+ *      Author: giulio moro
+ */
+#include "UdpServer.h"
+
+UdpServer::UdpServer(int aPort){
+	init(aPort);
+};
+UdpServer::UdpServer(){
+	init(0);
+}
+UdpServer::~UdpServer(){
+	close();
+};
+bool UdpServer::init(int aPort){
+	enabled=true;
+	stZeroTimeOut.tv_sec = 0; //set timeout to 0
+	stZeroTimeOut.tv_usec = 0;
+	inSocket=socket(AF_INET, SOCK_DGRAM, 0);
+	if (inSocket < 0){
+		enabled=false;
+	}
+	length = sizeof(server);
+	server.sin_family=AF_INET;
+	server.sin_addr.s_addr=INADDR_ANY;
+	enabled=bindToPort(aPort);
+	wasteBufferSize=2048;
+	wasteBuffer=malloc(wasteBufferSize);
+  memset(&stTimeOut,0,sizeof(struct timeval));
+	return enabled;
+}
+
+bool UdpServer::bindToPort(int aPort){
+	port=aPort;
+	if(port<1){
+		enabled=false;
+		return false;
+	}
+	server.sin_port=htons(port);
+	if (bind(inSocket,(struct sockaddr *)&server,length)<0){
+		enabled=false;
+		return false;
+	}
+	enabled=true;
+	return true;
+}
+
+void UdpServer::close(){
+	int ret=::close(inSocket);
+	if(ret != 0)
+		printf("Error while closing socket, errno: %d\n", errno);//Stop receiving data for this socket. If further data arrives, reject it.
+	inSocket=0;
+}
+
+int UdpServer::waitUntilReady(bool readyForReading, int timeoutMsecs){
+//	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.
+	if(enabled==false)
+		return -1;
+	if(timeoutMsecs<0)
+		return select(inSocket+1, &stReadFDS, NULL, NULL, NULL); //calling this with a NULL timeout will block indefinitely
+	FD_ZERO(&stReadFDS);
+	FD_SET(inSocket, &stReadFDS);
+	float timeOutSecs=timeoutMsecs*0.001;
+	stTimeOut.tv_sec=(long int)timeOutSecs;
+	timeOutSecs-=(int)timeOutSecs;
+	long int timeOutUsecs=timeOutSecs*1000000;
+	stTimeOut.tv_usec=timeOutUsecs;
+	int descriptorReady= select(inSocket+1, &stReadFDS, NULL, NULL, &stTimeOut);
+//	printf("stTimeOut.tv_sec=%ld, stTimeOut.tv_usec=%ld, descriptorReady: \n",stTimeOut.tv_sec,stTimeOut.tv_usec, descriptorReady);
+//	return descriptorReady>0 ? (timeOutUsecs-stTimeOut.tv_usec) : descriptorReady;
+	return descriptorReady>0 ? 1 : descriptorReady;
+}
+
+int UdpServer::read(//Returns the number of bytes read, or -1 if there was an error.
+					void *destBuffer,
+					int maxBytesToRead,
+					bool blockUntilSpecifiedAmountHasArrived)
+{
+	if(enabled==false)
+		return -1;
+	FD_ZERO(&stReadFDS);
+	FD_SET(inSocket, &stReadFDS);
+	int descriptorReady= select(inSocket+1, &stReadFDS, NULL, NULL, &stZeroTimeOut); //TODO: this is not JUCE-compliant
+	if(descriptorReady<0){ //an error occurred
+		return -1;
+	}
+	int numberOfBytes=0;
+//	do
+	{
+		if (FD_ISSET(inSocket, &stReadFDS))
+		{
+	//		numberOfBytes=recvfrom(inSocket,destBuffer,maxBytesToRead,0,(struct sockaddr *)&from,&fromLength);
+			numberOfBytes+=recv(inSocket,destBuffer,maxBytesToRead-numberOfBytes,0);
+			if(numberOfBytes<0)
+				return -1;
+		}
+	}
+//	while (blockUntilSpecifiedAmountHasArrived && numberOfBytes==maxBytesToRead);
+	return numberOfBytes;
+}
+int UdpServer::empty(){
+	return empty(0);
+}
+int UdpServer::empty(int maxCount){
+	int count=0;
+	int n;
+	do {
+		if(waitUntilReady(true, 0)==0)
+			return 0;
+		float waste;
+		n=read(&waste, sizeof(float), false);
+		count++;
+	} while (n>0 && (maxCount<=0 || maxCount<count));
+	printf("socket emptied with %d reads\n", count);
+	return count;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/UdpServer.h	Tue Feb 09 15:52:35 2016 +0000
@@ -0,0 +1,70 @@
+/*
+ * udpServer.h
+ *
+ *  Created on: 19 May 2015
+ *      Author: giulio moro
+ */
+
+#ifndef UDPSERVER_H_
+#define UDPSERVER_H_
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+class UdpServer{
+	private:
+		int port;
+		int enabled;
+		int inSocket;
+		struct sockaddr_in server;
+		struct timeval stTimeOut;
+		struct timeval stZeroTimeOut;
+		fd_set stReadFDS;
+		int size;
+		void *wasteBuffer;
+		int wasteBufferSize;
+		int length;
+		socklen_t fromLength;
+		struct sockaddr_in from;
+	public:
+		UdpServer();
+		UdpServer(int aPort);
+		~UdpServer();
+		bool init(int aPort);
+		bool bindToPort(int aPort);
+		int getBoundPort() const;
+		/*
+		 * Reads bytes from the socket.
+		 *
+		 * Drop-in replacement for JUCE DatagramSocket::read()
+		 *
+			If blockUntilSpecifiedAmountHasArrived is true, the method will block until maxBytesToRead
+			bytes have been read, (or until an error occurs). If this flag is false, the method will
+			return as much data as is currently available without blocking.
+		 */
+		int read(void* destBuffer, int maxBytesToRead, bool blockUntilSpecifiedAmountHasArrived);
+		void close();
+		int empty();
+		int empty(int maxCount);
+		/*
+		 * Waits until the socket is ready for reading or writing.
+		 *
+			Drop-in replacement for JUCE DatagramSocket::waitUntilReady.
+			If readyForReading is true, it will wait until the socket is ready for reading; if false, it will wait until it's ready for writing.
+			If the timeout is < 0, it will wait forever, or else will give up after the specified time.
+			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.
+		 */
+		int waitUntilReady(bool readyForReading, int timeoutMsecs);
+};
+
+
+
+#endif /* UDPSERVER_H_ */