From 1102153d2b66821fe45d7a31598dc24c1548c9c0 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Thu, 9 Aug 2018 15:43:56 +0200 Subject: [PATCH] Exceptions handling in constructor for genericSocket, created object to handle both socket descriptors upon throwing exception in constructor (as raw pointers wont get destructed automatically) --- slsDetectorGui/client/qClient.cpp | 48 +++-- slsDetectorGui/src/qServer.cpp | 22 +- .../slsADCReader/slsADCReader.cpp | 21 +- .../slsDetector/slsDetector.cpp | 113 ++++++----- slsReceiverSoftware/include/genericSocket.h | 190 +++++++++--------- slsReceiverSoftware/include/slsReceiver.h | 5 +- .../include/slsReceiverTCPIPInterface.h | 13 +- .../include/sls_receiver_exceptions.h | 9 +- slsReceiverSoftware/src/Listener.cpp | 27 ++- .../src/UDPBaseImplementation.cpp | 2 - slsReceiverSoftware/src/slsReceiver.cpp | 60 ++---- .../src/slsReceiverTCPIPInterface.cpp | 128 +++--------- slsReceiverSoftware/src/slsReceiverUsers.cpp | 17 +- slsReceiverSoftware/src/utilities.cpp | 11 +- 14 files changed, 309 insertions(+), 357 deletions(-) diff --git a/slsDetectorGui/client/qClient.cpp b/slsDetectorGui/client/qClient.cpp index e89eed56e..43cf62cd2 100644 --- a/slsDetectorGui/client/qClient.cpp +++ b/slsDetectorGui/client/qClient.cpp @@ -21,34 +21,44 @@ using namespace std; int main(int argc, char *argv[]){ - - qClient *cl =new qClient(argv[1]); + qClient* cl = 0; + try { + qClient *c = new qClient(argv[1]); + cl = c; + } catch(...) { + return 0; + } cl->executeLine(argc-2, argv+2); - delete cl; + + return 0; } //------------------------------------------------------------------------------------------------------------------------------------------------- -qClient::qClient(char* hostname){ - //create socket - mySocket = new MySocketTCP(hostname, DEFAULT_GUI_PORTNO); - if (mySocket->getErrorStatus()){ - cout << "Error: could not connect to host:" << hostname << " with port " << DEFAULT_GUI_PORTNO << endl; - delete mySocket; - exit(-1); - } +qClient::qClient(char* hostname): + mySocket(0), + myStopSocket(0){ - //create socket to connect to stop server - myStopSocket = new MySocketTCP(hostname, DEFAULT_GUI_PORTNO+1); - if (myStopSocket->getErrorStatus()){ - cout << "Error: could not connect to host:" << hostname << " with port " << DEFAULT_GUI_PORTNO + 1 << endl; - delete myStopSocket; - exit(-1); - } + try { + // control socket + MySocketTCP* s = new MySocketTCP(hostname, DEFAULT_GUI_PORTNO); + mySocket = s; + // stop socket + s = new MySocketTCP(hostname, DEFAULT_GUI_PORTNO+1); + myStopSocket = s; + } catch(...) { + if (mySocket == 0) + cout << "Error: could not connect to control server:" << + hostname << " with port " << DEFAULT_GUI_PORTNO << endl; + else + cout << "Error: could not connect to stop server:" << + hostname << " with port " << DEFAULT_GUI_PORTNO + 1 << endl; + throw; + } } @@ -93,7 +103,7 @@ int qClient::executeLine(int narg, char *args[]){ else if (argument == "stop") stopAcquisition(); else{ - cout << "Error: could not parse arguments: " << argument << endl; + cprintf(RED,"Error: could not parse arguments: %s\n", argument.c_str()); printCommands(); return FAIL; } diff --git a/slsDetectorGui/src/qServer.cpp b/slsDetectorGui/src/qServer.cpp index d818b88f8..9b83a8d9c 100644 --- a/slsDetectorGui/src/qServer.cpp +++ b/slsDetectorGui/src/qServer.cpp @@ -27,7 +27,7 @@ int qServer::gui_server_thread_running(0); qServer::qServer(qDetectorMain *t): - myMainTab(t), mySocket(NULL),myStopSocket(NULL),port_no(DEFAULT_GUI_PORTNO),lockStatus(0),checkStarted(0),checkStopStarted(0){ + myMainTab(t), mySocket(0),myStopSocket(0),port_no(DEFAULT_GUI_PORTNO),lockStatus(0),checkStarted(0),checkStopStarted(0){ strcpy(mess,""); FunctionTable(); @@ -196,7 +196,7 @@ int qServer::StartStopServer(int start){ pthread_join(gui_server_thread,NULL); if(mySocket){ delete mySocket; - mySocket = NULL; + mySocket = 0; } if(myStopSocket) @@ -204,7 +204,7 @@ int qServer::StartStopServer(int start){ pthread_join(gui_stop_server_thread,NULL); if(myStopSocket){ delete myStopSocket; - myStopSocket = NULL; + myStopSocket = 0; } } #ifdef VERBOSE @@ -235,8 +235,10 @@ int qServer::StopServer(){ #endif int ret = qDefs::OK; - myStopSocket = new MySocketTCP(port_no+1); - if (myStopSocket->getErrorStatus()){ + try { + MySocketTCP* s = new MySocketTCP(port_no+1); + myStopSocket = s; + } catch(...) { gui_server_thread_running = 0; qDefs::Message(qDefs::WARNING,"Could not start gui stop server socket","qServer::StopServer"); } @@ -270,7 +272,7 @@ int qServer::StopServer(){ //delete socket(via exit server) if(myStopSocket){ delete myStopSocket; - myStopSocket = NULL; + myStopSocket = 0; } if(!gui_server_thread_running) @@ -300,8 +302,10 @@ int qServer::StartServer(){ #endif int ret = qDefs::OK; - mySocket = new MySocketTCP(port_no); - if (mySocket->getErrorStatus()){ + try { + MySocketTCP* s = new MySocketTCP(port_no); + mySocket = s; + } catch(...) { gui_server_thread_running = 0; qDefs::Message(qDefs::WARNING,"Could not start gui server socket","qServer::StartServer"); } @@ -335,7 +339,7 @@ int qServer::StartServer(){ //delete socket(via exit server) if(mySocket){ delete mySocket; - mySocket = NULL; + mySocket = 0; } if(!gui_server_thread_running) diff --git a/slsDetectorSoftware/slsADCReader/slsADCReader.cpp b/slsDetectorSoftware/slsADCReader/slsADCReader.cpp index f27eb3a86..5f18a1514 100644 --- a/slsDetectorSoftware/slsADCReader/slsADCReader.cpp +++ b/slsDetectorSoftware/slsADCReader/slsADCReader.cpp @@ -88,24 +88,27 @@ int main(int argc, char* argv[]) int ret=slsReceiverDefs::FAIL; int arg[2]={idx,0}; + MySocketTCP* mySocket = 0; - MySocketTCP* tempSocket=new MySocketTCP(argv[1],1952); - if (tempSocket->getErrorStatus()){ + try { + MySocketTCP* s = new MySocketTCP(argv[1],1952); + mySocket = s; + } catch (...) { cerr << "could not create socket with " << argv[1] << endl; help(); } - if (tempSocket->Connect()) { - tempSocket->SendDataOnly(&fnum, sizeof(fnum)); - tempSocket->SendDataOnly(arg,sizeof(arg)); - tempSocket->ReceiveDataOnly(&ret, sizeof(ret)); + if (mySocket->Connect()) { + mySocket->SendDataOnly(&fnum, sizeof(fnum)); + mySocket->SendDataOnly(arg,sizeof(arg)); + mySocket->ReceiveDataOnly(&ret, sizeof(ret)); if (ret != slsReceiverDefs::FAIL) { - tempSocket->ReceiveDataOnly(&retval, sizeof(retval)); + mySocket->ReceiveDataOnly(&retval, sizeof(retval)); } else { - tempSocket->ReceiveDataOnly(mess,sizeof(mess)); + mySocket->ReceiveDataOnly(mess,sizeof(mess)); printf("Detector returned Error: %s",mess); } - tempSocket->Disconnect(); + mySocket->Disconnect(); } else cerr << "could not connect to " << argv[1] << endl; diff --git a/slsDetectorSoftware/slsDetector/slsDetector.cpp b/slsDetectorSoftware/slsDetector/slsDetector.cpp index 403610a81..ee8311f45 100644 --- a/slsDetectorSoftware/slsDetector/slsDetector.cpp +++ b/slsDetectorSoftware/slsDetector/slsDetector.cpp @@ -1287,29 +1287,39 @@ slsReceiverDefs::detectorType slsDetector::getDetectorTypeFromShm(int multiId, b slsDetectorDefs::detectorType slsDetector::getDetectorType(const char *name, int cport) { int fnum=F_GET_DETECTOR_TYPE; int retval = FAIL; - detectorType t=GENERIC; - MySocketTCP *s= new MySocketTCP(name, cport); + detectorType t = GENERIC; + MySocketTCP* mySocket = 0; + + try { + MySocketTCP* s= new MySocketTCP(name, cport); + mySocket = s; + } catch(...) { + cout << "Cannot create socket to server " << name << " over port " << cport << endl; + return t; + } + + char m[MAX_STR_LENGTH]; #ifdef VERBOSE cout << "Getting detector type " << endl; #endif - if (s->Connect() >= 0) { - s->SendDataOnly(&fnum,sizeof(fnum)); - s->ReceiveDataOnly(&retval,sizeof(retval)); + if (mySocket->Connect() >= 0) { + mySocket->SendDataOnly(&fnum,sizeof(fnum)); + mySocket->ReceiveDataOnly(&retval,sizeof(retval)); if (retval!=FAIL) { - s->ReceiveDataOnly(&t,sizeof(t)); + mySocket->ReceiveDataOnly(&t,sizeof(t)); #ifdef VERBOSE cout << "Detector type is "<< t << endl; #endif } else { - s->ReceiveDataOnly(m,sizeof(m)); + mySocket->ReceiveDataOnly(m,sizeof(m)); std::cout<< "Detector returned error: " << m << std::endl; } - s->Disconnect(); + mySocket->Disconnect(); } else { cout << "Cannot connect to server " << name << " over port " << cport << endl; } - delete s; + delete mySocket; return t; } @@ -1834,40 +1844,46 @@ int slsDetector::setTCPSocket(string const name, int const control_port, int con thisSP=thisDetector->stopPort; + // create control socket if (!controlSocket) { - controlSocket= new MySocketTCP(thisName, thisCP); - if (controlSocket->getErrorStatus()){ -#ifdef VERBOSE - std::cout<< "Could not connect Control socket " << thisName << " " - << thisCP << std::endl; -#endif - delete controlSocket; - controlSocket=NULL; - retval=FAIL; - } + try { + MySocketTCP* s = new MySocketTCP(thisName, thisCP); + controlSocket = s; #ifdef VERYVERBOSE - else - std::cout<< "Control socket connected " <getErrorStatus()){ -#ifdef VERBOSE - std::cout<< "Could not connect Stop socket "<getErrorStatus()){ -#ifdef VERBOSE - std::cout<< "Could not connect Data socket "<= 0) { + close(newfd); + } + // close socket descriptor + if (fd >= 0) { + close(fd); + } + } + /** socket descriptor */ + int fd; + /** new socket descriptor in TCP server from accept */ + int newfd; +}; + + + class genericSocket{ public: @@ -81,6 +87,7 @@ public: /** * The constructor for a client + * throws an exception if the hostname/ip could not be converted to an internet address * @param host_ip_or_name hostname or ip of the client * @param port_number port number to connect to * @param p TCP or UDP @@ -92,8 +99,6 @@ public: portno(port_number), protocol(p), is_a_server(0), - socketDescriptor(-1), - file_des(-1), packet_size(ps), nsending(0), nsent(0), @@ -108,20 +113,23 @@ public: differentClients = 0; struct addrinfo *result; - if (!ConvertHostnameToInternetAddress(host_ip_or_name, &result)) { - serverAddress.sin_family = result->ai_family; - memcpy((char *) &serverAddress.sin_addr.s_addr, - &((struct sockaddr_in *) result->ai_addr)->sin_addr, sizeof(in_addr_t)); - freeaddrinfo(result); - serverAddress.sin_port = htons(port_number); - socketDescriptor=0; + if (ConvertHostnameToInternetAddress(host_ip_or_name, &result)) { + sockfd.fd = -1; + throw SocketException(); } + + sockfd.fd = 0; + serverAddress.sin_family = result->ai_family; + memcpy((char *) &serverAddress.sin_addr.s_addr, + &((struct sockaddr_in *) result->ai_addr)->sin_addr, sizeof(in_addr_t)); + freeaddrinfo(result); + serverAddress.sin_port = htons(port_number); clientAddress_length=sizeof(clientAddress); }; /** * The constructor for a server - * throws an exception if + * throws an exception if socket could not be created, closes descriptor before throwing * @param port_number port number to connect to * @param p TCP or UDP * @param ps a single packet size @@ -133,8 +141,6 @@ public: portno(port_number), protocol(p), is_a_server(1), - socketDescriptor(-1), - file_des(-1), packet_size(ps), nsending(0), nsent(0), @@ -152,8 +158,8 @@ public: // same port if(serverAddress.sin_port == htons(port_number)){ - socketDescriptor = -10; - return; + sockfd.fd = -10; + throw SamePortSocketException(); } char ip[20]; @@ -166,11 +172,12 @@ public: strcpy(ip,eth); } - socketDescriptor = socket(AF_INET, getProtocol(),0); //tcp + sockfd.fd = socket(AF_INET, getProtocol(),0); //tcp - if (socketDescriptor < 0) { + if (sockfd.fd < 0) { cprintf(RED, "Can not create socket\n"); - return; + sockfd.fd =-1; + throw SocketException(); } // Set some fields in the serverAddress structure. @@ -189,15 +196,15 @@ public: // reuse port { int val=1; - if (setsockopt(socketDescriptor,SOL_SOCKET,SO_REUSEADDR, + if (setsockopt(sockfd.fd,SOL_SOCKET,SO_REUSEADDR, &val,sizeof(int)) == -1) { cprintf(RED, "setsockopt REUSEADDR failed\n"); - socketDescriptor=-1; - return; + sockfd.fd =-1; + throw SocketException(); } } - //increase buffer size if its udp + //increase socket buffer size if its udp if (p == UDP) { uint32_t desired_size = buf_size; uint32_t real_size = desired_size * 2; // kernel doubles this value for bookkeeping overhead @@ -205,7 +212,7 @@ public: socklen_t optlen = sizeof(int); // confirm if sufficient - if (getsockopt(socketDescriptor, SOL_SOCKET, SO_RCVBUF, &ret_size, &optlen) == -1) { + if (getsockopt(sockfd.fd, SOL_SOCKET, SO_RCVBUF, &ret_size, &optlen) == -1) { FILE_LOG(logWARNING) << "[Port " << port_number << "] " "Could not get rx socket receive buffer size"; } else if (ret_size >= real_size) { @@ -219,14 +226,14 @@ public: // not sufficient, enhance size else { // set buffer size (could not set) - if (setsockopt(socketDescriptor, SOL_SOCKET, SO_RCVBUF, + if (setsockopt(sockfd.fd, SOL_SOCKET, SO_RCVBUF, &desired_size, optlen) == -1) { FILE_LOG(logWARNING) << "[Port " << port_number << "] " "Could not set rx socket buffer size to " << desired_size << ". (No Root Privileges?)"; } // confirm size - else if (getsockopt(socketDescriptor, SOL_SOCKET, SO_RCVBUF, + else if (getsockopt(sockfd.fd, SOL_SOCKET, SO_RCVBUF, &ret_size, &optlen) == -1) { FILE_LOG(logWARNING) << "[Port " << port_number << "] " "Could not get rx socket buffer size"; @@ -241,9 +248,9 @@ public: actual_udp_socket_buffer_size = ret_size; // force a value larger than system limit // (if run in a privileged context (capability CAP_NET_ADMIN set)) - int ret = setsockopt(socketDescriptor, SOL_SOCKET, SO_RCVBUFFORCE, + int ret = setsockopt(sockfd.fd, SOL_SOCKET, SO_RCVBUFFORCE, &desired_size, optlen); - getsockopt(socketDescriptor, SOL_SOCKET, SO_RCVBUF, + getsockopt(sockfd.fd, SOL_SOCKET, SO_RCVBUF, &ret_size, &optlen); if (ret == -1) { FILE_LOG(logWARNING) << "[Port " << port_number << "] " @@ -261,15 +268,15 @@ public: } - if(bind(socketDescriptor,(struct sockaddr *) &serverAddress,sizeof(serverAddress))<0){ + if(bind(sockfd.fd,(struct sockaddr *) &serverAddress,sizeof(serverAddress))<0){ cprintf(RED, "Can not bind socket\n"); - socketDescriptor=-1; - return; + sockfd.fd =-1; + throw SocketException(); } if (getProtocol()==SOCK_STREAM) - listen(socketDescriptor, DEFAULT_BACKLOG); + listen(sockfd.fd, DEFAULT_BACKLOG); } @@ -277,8 +284,7 @@ public: * The destructor: disconnects and close the socket */ ~genericSocket() { - Disconnect(); - CloseServerTCPSocketDescriptor(); + //mySocketDescriptor destructor also gets called serverAddress.sin_port=-1; }; @@ -305,13 +311,13 @@ public: * Get TCP Server File Descriptor * @returns TCP Server file descriptor */ - int getFileDes(){return file_des;}; + int getFileDes(){return sockfd.newfd;}; /** * Get socket descriptor * @returns socket descriptor */ - int getsocketDescriptor(){return socketDescriptor;}; + int getsocketDescriptor(){return sockfd.fd;}; /** * Get total bytes sent/received @@ -343,21 +349,14 @@ public: */ int getProtocol() {return getProtocol(protocol);}; - /** - * Get error status - * @returns 1 if error - */ - int getErrorStatus(){if (socketDescriptor==-10) return -10; - else if (socketDescriptor<0) return 1; else return 0;}; - /** * Close TCP Server socket descriptor */ void CloseServerTCPSocketDescriptor() { - if (getProtocol() == TCP && is_a_server) { - if (socketDescriptor >= 0) { - close(socketDescriptor); - socketDescriptor = -1; + if (protocol == TCP && is_a_server) { + if (sockfd.fd >= 0) { + close(sockfd.fd); + sockfd.fd = -1; } } }; @@ -367,15 +366,15 @@ public: */ void Disconnect(){ if (protocol == TCP && is_a_server) { - if (file_des >= 0) { - close(file_des); - file_des = -1; + if (sockfd.newfd >= 0) { + close(sockfd.newfd); + sockfd.newfd = -1; } return; } - if (socketDescriptor >= 0) { - close(socketDescriptor); - socketDescriptor = -1; + if (sockfd.fd >= 0) { + close(sockfd.fd); + sockfd.fd = -1; } }; @@ -385,12 +384,12 @@ public: */ int Connect(){ - if(file_des>0) return file_des; + if(sockfd.newfd>0) return sockfd.newfd; if (protocol==UDP) return -1; if(is_a_server && protocol==TCP){ //server tcp; the server will wait for the clients connection - if (socketDescriptor>0) { - if ((file_des = accept(socketDescriptor,(struct sockaddr *) &clientAddress, &clientAddress_length)) < 0) { + if (sockfd.fd>0) { + if ((sockfd.newfd = accept(sockfd.fd,(struct sockaddr *) &clientAddress, &clientAddress_length)) < 0) { cprintf(RED, "Error: with server accept, connection refused\n"); switch(errno) { case EWOULDBLOCK: @@ -442,27 +441,27 @@ public: else{ inet_ntop(AF_INET, &(clientAddress.sin_addr), dummyClientIP, INET_ADDRSTRLEN); #ifdef VERY_VERBOSE - cout << "client connected "<< file_des << endl; + cout << "client connected "<< sockfd.newfd << endl; #endif } } #ifdef VERY_VERBOSE - cout << "fd " << file_des << endl; + cout << "fd " << sockfd.newfd << endl; #endif - return file_des; + return sockfd.newfd; } else { - if (socketDescriptor<=0) - socketDescriptor = socket(AF_INET, getProtocol(),0); + if (sockfd.fd<=0) + sockfd.fd = socket(AF_INET, getProtocol(),0); // SetTimeOut(10); - if (socketDescriptor < 0){ + if (sockfd.fd < 0){ cprintf(RED, "Can not create socket\n"); } else { - if(connect(socketDescriptor,(struct sockaddr *) &serverAddress,sizeof(serverAddress))<0){ + if(connect(sockfd.fd,(struct sockaddr *) &serverAddress,sizeof(serverAddress))<0){ cprintf(RED, "Can not connect to socket\n"); return -1; } } - return socketDescriptor; + return sockfd.fd; } }; @@ -478,7 +477,7 @@ public: * Shut down socket */ void ShutDownSocket(){ - shutdown(socketDescriptor, SHUT_RDWR); + shutdown(sockfd.fd, SHUT_RDWR); Disconnect(); }; @@ -494,13 +493,13 @@ public: struct timeval tout; tout.tv_sec = 0; tout.tv_usec = 0; - if(::setsockopt(socketDescriptor, SOL_SOCKET, SO_RCVTIMEO, + if(::setsockopt(sockfd.fd, SOL_SOCKET, SO_RCVTIMEO, &tout, sizeof(struct timeval)) <0) { cprintf(RED, "Error in setsockopt SO_RCVTIMEO %d\n", 0); } tout.tv_sec = ts; tout.tv_usec = 0; - if(::setsockopt(socketDescriptor, SOL_SOCKET, SO_SNDTIMEO, + if(::setsockopt(sockfd.fd, SOL_SOCKET, SO_SNDTIMEO, &tout, sizeof(struct timeval)) < 0) { cprintf(RED, "Error in setsockopt SO_SNDTIMEO %d\n", ts); } @@ -684,11 +683,11 @@ public: if (buf==NULL) return -1; total_sent=0; - int tcpfd = socketDescriptor; + int tcpfd = sockfd.fd; switch(protocol) { case TCP: - tcpfd = (is_a_server ? file_des : socketDescriptor); + tcpfd = (is_a_server ? sockfd.newfd : sockfd.fd); if (tcpfd<0) return -1; while(length>0){ nsending = (length>packet_size) ? packet_size:length; @@ -713,12 +712,12 @@ public: break; case UDP: - if (socketDescriptor<0) return -1; + if (sockfd.fd<0) return -1; //if length given, listens to length, else listens for packetsize till length is reached if(length){ while(length>0){ nsending = (length>packet_size) ? packet_size:length; - nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); + nsent = recvfrom(sockfd.fd,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); if(nsent == header_packet_size) continue; if(nsent != nsending){ @@ -738,7 +737,7 @@ public: #ifdef VERYVERBOSE cprintf(BLUE,"%d gonna listen\n", portno); fflush(stdout); #endif - nsent = recvfrom(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); + nsent = recvfrom(sockfd.fd,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, &clientAddress_length); //break out of loop only if read one packets size or read didnt work (cuz of shutdown) if(nsent<=0 || nsent == packet_size) break; @@ -773,11 +772,11 @@ public: total_sent=0; - int tcpfd = socketDescriptor; + int tcpfd = sockfd.fd; switch(protocol) { case TCP: - tcpfd = (is_a_server ? file_des : socketDescriptor); + tcpfd = (is_a_server ? sockfd.newfd : sockfd.fd); if (tcpfd<0) return -1; while(length>0){ nsending = (length>packet_size) ? packet_size:length; @@ -792,10 +791,10 @@ public: } break; case UDP: - if (socketDescriptor<0) return -1; + if (sockfd.fd<0) return -1; while(length>0){ nsending = (length>packet_size) ? packet_size:length; - nsent = sendto(socketDescriptor,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, clientAddress_length); + nsent = sendto(sockfd.fd,(char*)buf+total_sent,nsending, 0, (struct sockaddr *) &clientAddress, clientAddress_length); if(!nsent) break; length-=nsent; total_sent+=nsent; @@ -819,8 +818,7 @@ protected: int portno; communicationProtocol protocol; int is_a_server; - int socketDescriptor; - int file_des; + mySocketDescriptors sockfd; int packet_size; struct sockaddr_in clientAddress, serverAddress; socklen_t clientAddress_length; diff --git a/slsReceiverSoftware/include/slsReceiver.h b/slsReceiverSoftware/include/slsReceiver.h index 33cd4e7cf..896f63817 100644 --- a/slsReceiverSoftware/include/slsReceiver.h +++ b/slsReceiverSoftware/include/slsReceiver.h @@ -25,11 +25,11 @@ class slsReceiver : private virtual slsReceiverDefs { * Constructor * Starts up a Receiver server. Reads configuration file, options, and * assembles a Receiver using TCP and UDP detector interfaces + * throws an exception in case of failure * @param argc from command line * @param argv from command line - * @param succecc socket creation was successfull */ - slsReceiver(int argc, char *argv[], int &success); + slsReceiver(int argc, char *argv[]); /** * Destructor @@ -99,6 +99,5 @@ class slsReceiver : private virtual slsReceiverDefs { private: slsReceiverTCPIPInterface* tcpipInterface; - UDPInterface* udp_interface; }; diff --git a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h index 382c83c9e..6fd3df9ff 100644 --- a/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h +++ b/slsReceiverSoftware/include/slsReceiverTCPIPInterface.h @@ -26,21 +26,12 @@ class slsReceiverTCPIPInterface : private virtual slsReceiverDefs { /** * Constructor * reads config file, creates socket, assigns function table - * @param succecc socket creation was successfull - * @param rbase pointer to the receiver base + * throws an exception in case of failure to construct * @param pn port number (defaults to default port number) */ - slsReceiverTCPIPInterface(int &success, UDPInterface* rbase, int pn=-1); + slsReceiverTCPIPInterface(int pn=-1); - /** - * Sets the port number to listen to. - Take care that the client must know to whcih port it has to listen to, so normally it is better to use a fixes port from the instatiation or change it from the client. - @param pn port number (-1 only get) - \returns actual port number - */ - int setPortNumber(int pn=-1); - /** * Starts listening on the TCP port for client comminication \returns OK or FAIL diff --git a/slsReceiverSoftware/include/sls_receiver_exceptions.h b/slsReceiverSoftware/include/sls_receiver_exceptions.h index 32d4b011c..0996c8937 100644 --- a/slsReceiverSoftware/include/sls_receiver_exceptions.h +++ b/slsReceiverSoftware/include/sls_receiver_exceptions.h @@ -9,19 +9,18 @@ #include #include -using namespace std; -struct SharedMemoryException : public exception { +struct SharedMemoryException : public std::exception { public: SharedMemoryException() {} - string GetMessage() const { return "Shared Memory Failed";}; + std::string GetMessage() const { return "Shared Memory Failed";}; }; -struct ThreadpoolException : public exception { +struct ThreadpoolException : public std::exception { public: ThreadpoolException() {} - string GetMessage() const { return "Threadpool Failed";}; + std::string GetMessage() const { return "Threadpool Failed";}; }; struct SocketException : public std::exception { diff --git a/slsReceiverSoftware/src/Listener.cpp b/slsReceiverSoftware/src/Listener.cpp index 052345e2a..77dab1cef 100644 --- a/slsReceiverSoftware/src/Listener.cpp +++ b/slsReceiverSoftware/src/Listener.cpp @@ -193,16 +193,17 @@ int Listener::CreateUDPSockets() { ShutDownUDPSocket(); - udpSocket = new genericSocket(*udpPortNumber, genericSocket::UDP, - generalData->packetSize, (strlen(eth)?eth:NULL), generalData->headerPacketSize, - *udpSocketBufferSize); - int iret = udpSocket->getErrorStatus(); - if(!iret){ + try{ + genericSocket* g = new genericSocket(*udpPortNumber, genericSocket::UDP, + generalData->packetSize, (strlen(eth)?eth:NULL), generalData->headerPacketSize, + *udpSocketBufferSize); + udpSocket = g; FILE_LOG(logINFO) << index << ": UDP port opened at port " << *udpPortNumber; - }else{ - FILE_LOG(logERROR) << "Could not create UDP socket on port " << *udpPortNumber << " error: " << iret; + } catch (...) { + FILE_LOG(logERROR) << "Could not create UDP socket on port " << *udpPortNumber; return FAIL; } + udpSocketAlive = true; sem_init(&semaphore_socket,1,0); @@ -248,17 +249,21 @@ int Listener::CreateDummySocketForUDPSocketBufferSize(uint32_t s) { if(udpSocket){ udpSocket->ShutDownSocket(); delete udpSocket; + udpSocket = 0; } //create dummy socket - udpSocket = new genericSocket(*udpPortNumber, genericSocket::UDP, + try { + genericSocket* g = new genericSocket(*udpPortNumber, genericSocket::UDP, generalData->packetSize, (strlen(eth)?eth:NULL), generalData->headerPacketSize, *udpSocketBufferSize); - int iret = udpSocket->getErrorStatus(); - if (iret){ - FILE_LOG(logERROR) << "Could not create a test UDP socket on port " << *udpPortNumber << " error: " << iret; + udpSocket = g; + } catch (...) { + FILE_LOG(logERROR) << "Could not create a test UDP socket on port " << *udpPortNumber; return FAIL; } + + // doubled due to kernel bookkeeping (could also be less due to permissions) *actualUDPSocketBufferSize = udpSocket->getActualUDPSocketBufferSize(); if (*actualUDPSocketBufferSize != (s*2)) { diff --git a/slsReceiverSoftware/src/UDPBaseImplementation.cpp b/slsReceiverSoftware/src/UDPBaseImplementation.cpp index 69f25ce98..448051b55 100644 --- a/slsReceiverSoftware/src/UDPBaseImplementation.cpp +++ b/slsReceiverSoftware/src/UDPBaseImplementation.cpp @@ -5,8 +5,6 @@ ***********************************************/ #include "UDPBaseImplementation.h" -#include "genericSocket.h" -#include "ZmqSocket.h" #include // stat #include diff --git a/slsReceiverSoftware/src/slsReceiver.cpp b/slsReceiverSoftware/src/slsReceiver.cpp index 370fcd030..33bcf8c6b 100644 --- a/slsReceiverSoftware/src/slsReceiver.cpp +++ b/slsReceiverSoftware/src/slsReceiver.cpp @@ -18,11 +18,8 @@ using namespace std; -slsReceiver::slsReceiver(int argc, char *argv[], int &success): - tcpipInterface (NULL), - udp_interface (NULL) -{ - success=OK; +slsReceiver::slsReceiver(int argc, char *argv[]): + tcpipInterface (0) { // options map configuration_map; @@ -72,8 +69,7 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success): tempval = GITREV; tempval = (tempval <<32) | GITDATE; cout << "SLS Receiver " << GITBRANCH << " (0x" << hex << tempval << ")" << endl; - success = FAIL; // to exit - break; + throw exception(); case 'h': default: @@ -87,26 +83,18 @@ slsReceiver::slsReceiver(int argc, char *argv[], int &success): + "\t receivers\n\n"; FILE_LOG(logINFO) << help_message << endl; - break; + throw exception(); } } - if( !fname.empty() ){ - try{ - FILE_LOG(logINFO) << "config file name " << fname; - success = read_config_file(fname, &tcpip_port_no, &configuration_map); - //VERBOSE_PRINT("Read configuration file of " + iline + " lines"); - } - catch(...){ - FILE_LOG(logERROR) << "Coult not open configuration file " << fname ; - success = FAIL; - } + if( !fname.empty() && read_config_file(fname, &tcpip_port_no, &configuration_map) == FAIL) { + throw exception(); } - if (success==OK){ - tcpipInterface = new slsReceiverTCPIPInterface(success, udp_interface, tcpip_port_no); - } + // might throw an exception + tcpipInterface = new slsReceiverTCPIPInterface(tcpip_port_no); + } @@ -131,40 +119,26 @@ int64_t slsReceiver::getReceiverVersion(){ } -void slsReceiver::registerCallBackStartAcquisition(int (*func)(char*, char*, uint64_t, uint32_t, void*),void *arg){ - //tcpipInterface - if(udp_interface) - udp_interface->registerCallBackStartAcquisition(func,arg); - else - tcpipInterface->registerCallBackStartAcquisition(func,arg); +void slsReceiver::registerCallBackStartAcquisition(int (*func)( + char*, char*, uint64_t, uint32_t, void*),void *arg){ + tcpipInterface->registerCallBackStartAcquisition(func,arg); } -void slsReceiver::registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg){ - //tcpipInterface - if(udp_interface) - udp_interface->registerCallBackAcquisitionFinished(func,arg); - else - tcpipInterface->registerCallBackAcquisitionFinished(func,arg); +void slsReceiver::registerCallBackAcquisitionFinished( + void (*func)(uint64_t, void*),void *arg){ + tcpipInterface->registerCallBackAcquisitionFinished(func,arg); } void slsReceiver::registerCallBackRawDataReady(void (*func)(char*, char*, uint32_t, void*),void *arg){ - //tcpipInterface - if(udp_interface) - udp_interface->registerCallBackRawDataReady(func,arg); - else - tcpipInterface->registerCallBackRawDataReady(func,arg); + tcpipInterface->registerCallBackRawDataReady(func,arg); } void slsReceiver::registerCallBackRawDataModifyReady(void (*func)(char*, char*, uint32_t &, void*),void *arg){ - //tcpipInterface - if(udp_interface) - udp_interface->registerCallBackRawDataModifyReady(func,arg); - else - tcpipInterface->registerCallBackRawDataModifyReady(func,arg); + tcpipInterface->registerCallBackRawDataModifyReady(func,arg); } diff --git a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp index 07c0f84ac..06566fabf 100644 --- a/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp +++ b/slsReceiverSoftware/src/slsReceiverTCPIPInterface.cpp @@ -31,16 +31,16 @@ slsReceiverTCPIPInterface::~slsReceiverTCPIPInterface() { delete receiverBase; } -slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, UDPInterface* rbase, int pn): +slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int pn): myDetectorType(GOTTHARD), - receiverBase(rbase), + receiverBase(0), ret(OK), fnum(-1), lockStatus(0), killTCPServerThread(0), tcpThreadCreated(false), portNumber(DEFAULT_PORTNO+2), - mySock(NULL) + mySock(0) { //***callback parameters*** startAcquisitionCallBack = NULL; @@ -51,83 +51,25 @@ slsReceiverTCPIPInterface::slsReceiverTCPIPInterface(int &success, UDPInterface* rawDataModifyReadyCallBack = NULL; pRawDataReady = NULL; - unsigned short int port_no=portNumber; - if(receiverBase == NULL) - receiverBase = 0; + // create socket + portNumber = (pn > 0 ? pn : DEFAULT_PORTNO + 2); + MySocketTCP* m = new MySocketTCP(portNumber); + mySock = m; - if (pn>0) - port_no = pn; + //initialize variables + strcpy(mySock->lastClientIP,"none"); + strcpy(mySock->thisClientIP,"none1"); + memset(mess,0,sizeof(mess)); + strcpy(mess,"dummy message"); - success=OK; - - //create socket - if(success == OK){ - mySock = new MySocketTCP(port_no); - if (mySock->getErrorStatus()) { - success = FAIL; - delete mySock; - mySock=NULL; - } else { - portNumber=port_no; - //initialize variables - strcpy(mySock->lastClientIP,"none"); - strcpy(mySock->thisClientIP,"none1"); - memset(mess,0,sizeof(mess)); - strcpy(mess,"dummy message"); - function_table(); + function_table(); #ifdef VERYVERBOSE - FILE_LOG(logINFO) << "Function table assigned."; + FILE_LOG(logINFO) << "Function table assigned."; #endif - } - } } -int slsReceiverTCPIPInterface::setPortNumber(int pn){ - memset(mess, 0, sizeof(mess)); - int p_number; - - MySocketTCP *oldsocket = NULL;; - int sd = 0; - - if (pn > 0) { - p_number = pn; - - if (p_number < 1024) { - sprintf(mess,"Too low port number %d\n", p_number); - FILE_LOG(logERROR) << mess; - } else { - - oldsocket=mySock; - mySock = new MySocketTCP(p_number); - if(mySock){ - sd = mySock->getErrorStatus(); - if (!sd){ - portNumber=p_number; - strcpy(mySock->lastClientIP,oldsocket->lastClientIP); - delete oldsocket; - } else { - FILE_LOG(logERROR) << "Could not bind port " << p_number; - if (sd == -10) { - FILE_LOG(logINFO) << "Port "<< p_number << " already set"; - } else { - delete mySock; - mySock=oldsocket; - } - } - - } else { - mySock=oldsocket; - } - } - } - - return portNumber; -} - - - int slsReceiverTCPIPInterface::start(){ FILE_LOG(logDEBUG) << "Creating TCP Server Thread"; killTCPServerThread = 0; @@ -566,15 +508,14 @@ int slsReceiverTCPIPInterface::get_last_client_ip() { int slsReceiverTCPIPInterface::set_port() { ret = OK; memset(mess, 0, sizeof(mess)); - int unused = 0; + int p_type = 0; int p_number = -1; - MySocketTCP* mySocket = NULL; + MySocketTCP* mySocket = 0; char oldLastClientIP[INET_ADDRSTRLEN]; memset(oldLastClientIP, 0, sizeof(oldLastClientIP)); - int sd = -1; // receive arguments - if (mySock->ReceiveDataOnly(&unused,sizeof(unused)) < 0 ) + if (mySock->ReceiveDataOnly(&p_type,sizeof(p_type)) < 0 ) return printSocketReadError(); if (mySock->ReceiveDataOnly(&p_number,sizeof(p_number)) < 0 ) return printSocketReadError(); @@ -586,29 +527,26 @@ int slsReceiverTCPIPInterface::set_port() { FILE_LOG(logERROR) << mess; } else { - if (p_number<1024) { + if (p_number < 1024) { ret = FAIL; sprintf(mess,"Port Number (%d) too low\n", p_number); FILE_LOG(logERROR) << mess; - } - FILE_LOG(logINFO) << "set port to " << p_number <lastClientIP); - mySocket = new MySocketTCP(p_number); + } else { + FILE_LOG(logINFO) << "set port to " << p_number <lastClientIP); - if(mySocket){ - sd = mySocket->getErrorStatus(); - if (sd < 0) { - ret = FAIL; - sprintf(mess,"Could not bind port %d\n", p_number); - FILE_LOG(logERROR) << mess; - if (sd == -10) { - ret = FAIL; - sprintf(mess,"Port %d already set\n", p_number); - FILE_LOG(logERROR) << mess; - } - } - else + try { + mySocket = new MySocketTCP(p_number); strcpy(mySock->lastClientIP,oldLastClientIP); + } catch(SamePortSocketException e) { + ret = FAIL; + sprintf(mess, "Could not bind port %d. It is already set\n", p_number); + FILE_LOG(logERROR) << mess; + } catch (...) { + ret = FAIL; + sprintf(mess, "Could not bind port %d.\n", p_number); + FILE_LOG(logERROR) << mess; + } } } @@ -621,7 +559,7 @@ int slsReceiverTCPIPInterface::set_port() { mySock->SendDataOnly(mess,sizeof(mess)); else { mySock->SendDataOnly(&p_number,sizeof(p_number)); - if(sd>=0){ + if(ret != FAIL){ mySock->Disconnect(); delete mySock; mySock = mySocket; diff --git a/slsReceiverSoftware/src/slsReceiverUsers.cpp b/slsReceiverSoftware/src/slsReceiverUsers.cpp index 6b38ccd98..f65751dbb 100644 --- a/slsReceiverSoftware/src/slsReceiverUsers.cpp +++ b/slsReceiverSoftware/src/slsReceiverUsers.cpp @@ -2,11 +2,18 @@ #include "slsReceiver.h" slsReceiverUsers::slsReceiverUsers(int argc, char *argv[], int &success) { - receiver=new slsReceiver(argc, argv, success); + // catch the exception here to limit it to within the library (for current version) + try { + slsReceiver* r = new slsReceiver(argc, argv); + receiver = r; + success = slsReceiverDefs::OK; + } catch (...) { + success = slsReceiverDefs::FAIL; + } } slsReceiverUsers::~slsReceiverUsers() { - delete receiver; + delete receiver; } int slsReceiverUsers::start() { @@ -28,13 +35,13 @@ void slsReceiverUsers::registerCallBackStartAcquisition(int (*func)(char*, char* void slsReceiverUsers::registerCallBackAcquisitionFinished(void (*func)(uint64_t, void*),void *arg){ receiver->registerCallBackAcquisitionFinished(func,arg); } - + void slsReceiverUsers::registerCallBackRawDataReady(void (*func)(char* header, char* datapointer, uint32_t datasize, void*), void *arg){ receiver->registerCallBackRawDataReady(func,arg); } void slsReceiverUsers::registerCallBackRawDataModifyReady(void (*func)(char* header, - char* datapointer, uint32_t& revDatasize, void*), void *arg){ - receiver->registerCallBackRawDataModifyReady(func,arg); + char* datapointer, uint32_t& revDatasize, void*), void *arg){ + receiver->registerCallBackRawDataModifyReady(func,arg); } diff --git a/slsReceiverSoftware/src/utilities.cpp b/slsReceiverSoftware/src/utilities.cpp index 253f1f229..ebcc90014 100644 --- a/slsReceiverSoftware/src/utilities.cpp +++ b/slsReceiverSoftware/src/utilities.cpp @@ -8,6 +8,7 @@ #include #include "utilities.h" +#include "logger.h" using namespace std; @@ -21,9 +22,15 @@ int read_config_file(string fname, int *tcpip_port_no, map * con int success = slsReceiverDefs::OK; + FILE_LOG(logINFO) << "config file name " << fname; + try { + infile.open(fname.c_str(), ios_base::in); + } catch(...) { + FILE_LOG(logERROR) << "Could not open configuration file " << fname ; + success = slsReceiverDefs::FAIL; + } - infile.open(fname.c_str(), ios_base::in); - if (infile.is_open()) { + if (success == slsReceiverDefs::OK && infile.is_open()) { while(infile.good()){ getline(infile,sLine); iline++;