From 16e83c0afcec0cea8af82189d4e98cd232bdf154 Mon Sep 17 00:00:00 2001 From: Tobias Frust Date: Wed, 29 Jun 2016 14:49:55 +0200 Subject: created project structure --- .gitignore | 3 ++ src/CMakeLists.txt | 40 +++++++++++++++++++ src/CMakeLists.txt~ | 38 ++++++++++++++++++ src/DetectorModule/DetectorModule.cpp | 0 src/DetectorModule/DetectorModule.h | 0 src/cmake/FindLibConfig.cmake | 73 +++++++++++++++++++++++++++++++++++ src/main.cpp | 0 7 files changed, 154 insertions(+) create mode 100644 src/CMakeLists.txt create mode 100644 src/CMakeLists.txt~ create mode 100644 src/DetectorModule/DetectorModule.cpp create mode 100644 src/DetectorModule/DetectorModule.h create mode 100644 src/cmake/FindLibConfig.cmake create mode 100644 src/main.cpp diff --git a/.gitignore b/.gitignore index 4581ef2..159a010 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,6 @@ *.exe *.out *.app + +build/* + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..4c09b2e --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.5) +project(OnlineDetectorSimulator) + +#define some speciel output paths for libraries and executables +set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) +set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) + +#use c++11 +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(Boost_USE_MULTITHREADED ON) +SET(BOOST_MIN_VERSION "1.58.0") +add_definitions(-DBOOST_LOG_DYN_LINK=1) + +#find required packages +find_package(LibConfig REQUIRED) +find_package(Boost ${BOOST_MIN_VERSION} REQUIRED COMPONENTS log filesystem) +find_package(OpenMP) + +#add openmp +if(OPENMP_FOUND) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") +endif() + +include_directories( + ${LIBCONFIGPP_INCLUDE_DIR} + ${BOOST_INCLUDE_DIRS} +) + +file(GLOB SOURCES + "*.cpp" +) + +add_executable(onlineDetectorSimulator ${SOURCES}) + + diff --git a/src/CMakeLists.txt~ b/src/CMakeLists.txt~ new file mode 100644 index 0000000..36ea910 --- /dev/null +++ b/src/CMakeLists.txt~ @@ -0,0 +1,38 @@ +cmake_minimum_required(VERSION 3.5) +project(OnlineDetectorSimulator) + +#define some speciel output paths for libraries and executables +set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin) +set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) + +#use c++11 +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(Boost_USE_MULTITHREADED ON) +SET(BOOST_MIN_VERSION "1.58.0") +add_definitions(-DBOOST_LOG_DYN_LINK=1) + +#find required packages +find_package(LibConfig REQUIRED) +find_package(Boost ${BOOST_MIN_VERSION} REQUIRED COMPONENTS log filesystem) +find_package(OpenMP) + +#add openmp +if(OPENMP_FOUND) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}") +endif() + +include_directories( + ${LIBCONFIGPP_INCLUDE_DIR} + ${BOOST_INCLUDE_DIRS} +) + +file(GLOB SOURCES + "*.cpp" +) + + diff --git a/src/DetectorModule/DetectorModule.cpp b/src/DetectorModule/DetectorModule.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/DetectorModule/DetectorModule.h b/src/DetectorModule/DetectorModule.h new file mode 100644 index 0000000..e69de29 diff --git a/src/cmake/FindLibConfig.cmake b/src/cmake/FindLibConfig.cmake new file mode 100644 index 0000000..436d2a5 --- /dev/null +++ b/src/cmake/FindLibConfig.cmake @@ -0,0 +1,73 @@ +# Find the CUnit includes and library +# +# This module defines +# LIBCONFIG_INCLUDE_DIR, where to find cppunit include files, etc. +# LIBCONFIG_LIBRARIES, the libraries to link against to use CppUnit. +# LIBCONFIG_STATIC_LIBRARIY_PATH +# LIBCONFIG_FOUND, If false, do not try to use CppUnit. + +# also defined, but not for general use are +# LIBCONFIG_LIBRARY, where to find the CUnit library. + +#MESSAGE("Searching for libconfig library") + +FIND_PATH(LIBCONFIG_INCLUDE_DIR libconfig.h + /usr/local/include + /usr/include +) + +FIND_PATH(LIBCONFIGPP_INCLUDE_DIR libconfig.h++ + /usr/local/include + /usr/include +) + +FIND_LIBRARY(LIBCONFIG_LIBRARY config + /usr/local/lib + /usr/lib +) + +FIND_LIBRARY(LIBCONFIGPP_LIBRARY config++ + /usr/local/lib + /usr/lib +) + +FIND_LIBRARY(LIBCONFIG_STATIC_LIBRARY "libconfig${CMAKE_STATIC_LIBRARY_SUFFIX}" + /usr/local/lib + /usr/lib +) + +FIND_LIBRARY(LIBCONFIGPP_STATIC_LIBRARY "libconfig++${CMAKE_STATIC_LIBRARY_SUFFIX}" + /usr/local/lib + /usr/lib +) + + +IF(LIBCONFIG_INCLUDE_DIR) + IF(LIBCONFIG_LIBRARY) + SET(LIBCONFIG_FOUND TRUE) + SET(LIBCONFIG_LIBRARIES ${LIBCONFIG_LIBRARY}) + SET(LIBCONFIG_STATIC_LIBRARY_PATH ${LIBCONFIG_STATIC_LIBRARY}) + ENDIF(LIBCONFIG_LIBRARY) +ENDIF(LIBCONFIG_INCLUDE_DIR) + +IF(LIBCONFIGPP_INCLUDE_DIR) + IF(LIBCONFIGPP_LIBRARY) + SET(LIBCONFIGPP_FOUND TRUE) + SET(LIBCONFIGPP_LIBRARIES ${LIBCONFIGPP_LIBRARY}) + SET(LIBCONFIGPP_STATIC_LIBRARY_PATH ${LIBCONFIGPP_STATIC_LIBRARY}) + ENDIF(LIBCONFIGPP_LIBRARY) +ENDIF(LIBCONFIGPP_INCLUDE_DIR) + +IF (LIBCONFIG_FOUND) + IF (NOT LibConfig_FIND_QUIETLY) + MESSAGE(STATUS "Found LibConfig++: ${LIBCONFIGPP_LIBRARIES}" ) + MESSAGE(STATUS "Found LibConfig: ${LIBCONFIG_LIBRARIES}") + MESSAGE(STATUS "static LibConfig path: ${LIBCONFIG_STATIC_LIBRARY_PATH}") + ENDIF (NOT LibConfig_FIND_QUIETLY) +ELSE (LIBCONFIG_FOUND) + IF (LibConfig_FIND_REQUIRED) + MESSAGE(SEND_ERROR "Could NOT find LibConfig") + ENDIF (LibConfig_FIND_REQUIRED) +ENDIF (LIBCONFIG_FOUND) + +MARK_AS_ADVANCED(LIBCONFIG_INCLUDE_DIR LIBCONFIG_LIBRARIES) diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..e69de29 -- cgit v1.2.1 From 5ecc4dde3731724f28d4629f8a563f30bb260617 Mon Sep 17 00:00:00 2001 From: Tobias Frust Date: Wed, 29 Jun 2016 15:22:50 +0200 Subject: added udpClient, which will later send out the packages --- src/DetectorModule/DetectorModule.cpp | 9 +++++++++ src/DetectorModule/DetectorModule.h | 24 ++++++++++++++++++++++++ src/UDPClient/UDPClient.cpp | 12 ++++++++++++ src/UDPClient/UDPClient.h | 15 +++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 src/UDPClient/UDPClient.cpp create mode 100644 src/UDPClient/UDPClient.h diff --git a/src/DetectorModule/DetectorModule.cpp b/src/DetectorModule/DetectorModule.cpp index e69de29..ac9ee27 100644 --- a/src/DetectorModule/DetectorModule.cpp +++ b/src/DetectorModule/DetectorModule.cpp @@ -0,0 +1,9 @@ +/* + * Copyright 2016 Tobias Frust + * + * DetectorModule.cpp + * + * Created on: 29.06.2016 + * Author: Tobias Frust + */ + diff --git a/src/DetectorModule/DetectorModule.h b/src/DetectorModule/DetectorModule.h index e69de29..aa63d82 100644 --- a/src/DetectorModule/DetectorModule.h +++ b/src/DetectorModule/DetectorModule.h @@ -0,0 +1,24 @@ +/* + * Copyright 2016 Tobias Frust + * + * DetectorModule.h + * + * Created on: 29.06.2016 + * Author: Tobias Frust + */ + +#ifndef DETECTORMODULE_H_ +#define DETECTORMODULE_H_ + +#include + +template +class DetectorModule { +public: + DetectorModule(); + +private: + std::vector> buffer_; +}; + +#endif diff --git a/src/UDPClient/UDPClient.cpp b/src/UDPClient/UDPClient.cpp new file mode 100644 index 0000000..640555f --- /dev/null +++ b/src/UDPClient/UDPClient.cpp @@ -0,0 +1,12 @@ +/* + * Copyright 2016 Tobias Frust + * + * UDPSender.cpp + * + * Created on: 29.06.2016 + * Author: Tobias Frust + */ + + + + diff --git a/src/UDPClient/UDPClient.h b/src/UDPClient/UDPClient.h new file mode 100644 index 0000000..a962fe9 --- /dev/null +++ b/src/UDPClient/UDPClient.h @@ -0,0 +1,15 @@ +/* + * Copyright 2016 Tobias Frust + * + * UDPSender.h + * + * Created on: 29.06.2016 + * Author: Tobias Frust + */ + +#ifndef UDPSENDER_H_ +#define UDPSENDER_H_ + + + +#endif /* UDPSENDER_H_ */ -- cgit v1.2.1 From 38b0d8ad024d11fa643934b0c56690b0e57c3e35 Mon Sep 17 00:00:00 2001 From: Tobias Frust Date: Wed, 29 Jun 2016 19:16:11 +0200 Subject: added UDP-Client and Server classes for data transfer via Ethernet --- src/CMakeLists.txt | 5 +- src/UDPClient/UDPClient.cpp | 130 +++++++++++++++++++++++++++++- src/UDPClient/UDPClient.h | 37 ++++++++- src/UDPServer/UDPServer.cpp | 188 ++++++++++++++++++++++++++++++++++++++++++++ src/UDPServer/UDPServer.h | 39 +++++++++ src/main.cpp | 22 ++++++ 6 files changed, 414 insertions(+), 7 deletions(-) create mode 100644 src/UDPServer/UDPServer.cpp create mode 100644 src/UDPServer/UDPServer.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4c09b2e..746b901 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -31,8 +31,9 @@ include_directories( ${BOOST_INCLUDE_DIRS} ) -file(GLOB SOURCES - "*.cpp" +set(SOURCES + "${CMAKE_SOURCE_DIR}/UDPClient/UDPClient.cpp" + "${CMAKE_SOURCE_DIR}/main.cpp" ) add_executable(onlineDetectorSimulator ${SOURCES}) diff --git a/src/UDPClient/UDPClient.cpp b/src/UDPClient/UDPClient.cpp index 640555f..75e81e1 100644 --- a/src/UDPClient/UDPClient.cpp +++ b/src/UDPClient/UDPClient.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2016 Tobias Frust + * http://linux.m2osw.com/c-implementation-udp-clientserver * * UDPSender.cpp * @@ -7,6 +7,134 @@ * Author: Tobias Frust */ + // ========================= CLIENT ========================= + /** \brief Initialize a UDP client object. + * + * This function initializes the UDP client object using the address and the + * port as specified. + * + * The port is expected to be a host side port number (i.e. 59200). + * + * The \p addr parameter is a textual address. It may be an IPv4 or IPv6 + * address and it can represent a host name or an address defined with + * just numbers. If the address cannot be resolved then an error occurs + * and constructor throws. + * + * \note + * The socket is open in this process. If you fork() or exec() then the + * socket will be closed by the operating system. + * + * \warning + * We only make use of the first address found by getaddrinfo(). All + * the other addresses are ignored. + * + * \exception udp_client_server_runtime_error + * The server could not be initialized properly. Either the address cannot be + * resolved, the port is incompatible or not available, or the socket could + * not be created. + * + * \param[in] addr The address to convert to a numeric IP. + * \param[in] port The port number. + */ +#include "UDPClient.h" +#include +#include + +#ifndef SOCK_CLOEXEC +#define SOCK_CLOEXEC 0 +#endif + + UDPClient::UDPClient(const std::string& addr, int port) + : f_port(port) + , f_addr(addr){ + char decimal_port[16]; + snprintf(decimal_port, sizeof(decimal_port), "%d", f_port); + decimal_port[sizeof(decimal_port) / sizeof(decimal_port[0]) - 1] = '\0'; + struct addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + int r(getaddrinfo(addr.c_str(), decimal_port, &hints, &f_addrinfo)); + if(r != 0 || f_addrinfo == NULL) + { + throw udp_client_server_runtime_error(("invalid address or port: \"" + addr + ":" + decimal_port + "\"").c_str()); + } + f_socket = socket(f_addrinfo->ai_family, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP); + if(f_socket == -1) + { + freeaddrinfo(f_addrinfo); + throw udp_client_server_runtime_error(("could not create socket for: \"" + addr + ":" + decimal_port + "\"").c_str()); + } + } + + /** \brief Clean up the UDP client object. + * + * This function frees the address information structure and close the socket + * before returning. + */ + UDPClient::~UDPClient() + { + freeaddrinfo(f_addrinfo); + close(f_socket); + } + + /** \brief Retrieve a copy of the socket identifier. + * + * This function return the socket identifier as returned by the socket() + * function. This can be used to change some flags. + * + * \return The socket used by this UDP client. + */ + int UDPClient::get_socket() const { + return f_socket; + } + + /** \brief Retrieve the port used by this UDP client. + * + * This function returns the port used by this UDP client. The port is + * defined as an integer, host side. + * + * \return The port as expected in a host integer. + */ + int UDPClient::get_port() const { + return f_port; + } + + /** \brief Retrieve a copy of the address. + * + * This function returns a copy of the address as it was specified in the + * constructor. This does not return a canonalized version of the address. + * + * The address cannot be modified. If you need to send data on a different + * address, create a new UDP client. + * + * \return A string with a copy of the constructor input address. + */ + std::string UDPClient::get_addr() const { + return f_addr; + } + + /** \brief Send a message through this UDP client. + * + * This function sends \p msg through the UDP client socket. The function + * cannot be used to change the destination as it was defined when creating + * the udp_client object. + * + * The size must be small enough for the message to fit. In most cases we + * use these in Snap! to send very small signals (i.e. 4 bytes commands.) + * Any data we would want to share remains in the Cassandra database so + * that way we can avoid losing it because of a UDP message. + * + * \param[in] msg The message to send. + * \param[in] size The number of bytes representing this message. + * + * \return -1 if an error occurs, otherwise the number of bytes sent. errno + * is set accordingly on error. + */ + int UDPClient::send(const char *msg, size_t size){ + return sendto(f_socket, msg, size, 0, f_addrinfo->ai_addr, f_addrinfo->ai_addrlen); + } diff --git a/src/UDPClient/UDPClient.h b/src/UDPClient/UDPClient.h index a962fe9..f6cf0d6 100644 --- a/src/UDPClient/UDPClient.h +++ b/src/UDPClient/UDPClient.h @@ -1,5 +1,5 @@ /* - * Copyright 2016 Tobias Frust + * http://linux.m2osw.com/c-implementation-udp-clientserver * * UDPSender.h * @@ -7,9 +7,38 @@ * Author: Tobias Frust */ -#ifndef UDPSENDER_H_ -#define UDPSENDER_H_ +#ifndef UDPCLIENT_H_ +#define UDPCLIENT_H_ +#include +#include +#include +#include +#include +class udp_client_server_runtime_error : public std::runtime_error +{ +public: + udp_client_server_runtime_error(const char *w) : std::runtime_error(w) {} +}; -#endif /* UDPSENDER_H_ */ + +class UDPClient { +public: + UDPClient(const std::string& addr, int port); + ~UDPClient(); + + int get_socket() const; + int get_port() const; + std::string get_addr() const; + + int send(const char *msg, size_t size); + +private: + int f_socket; + int f_port; + std::string f_addr; + struct addrinfo * f_addrinfo; +}; + +#endif /* UDPCLIENT_H_ */ diff --git a/src/UDPServer/UDPServer.cpp b/src/UDPServer/UDPServer.cpp new file mode 100644 index 0000000..cd36647 --- /dev/null +++ b/src/UDPServer/UDPServer.cpp @@ -0,0 +1,188 @@ +/* + * http://linux.m2osw.com/c-implementation-udp-clientserver + * + * UDPServer.cpp + * + * Created on: 29.06.2016 + * Author: Tobias Frust + */ + +// ========================= SEVER ========================= + +/** \brief Initialize a UDP server object. + * + * This function initializes a UDP server object making it ready to + * receive messages. + * + * The server address and port are specified in the constructor so + * if you need to receive messages from several different addresses + * and/or port, you'll have to create a server for each. + * + * The address is a string and it can represent an IPv4 or IPv6 + * address. + * + * Note that this function calls connect() to connect the socket + * to the specified address. To accept data on different UDP addresses + * and ports, multiple UDP servers must be created. + * + * \note + * The socket is open in this process. If you fork() or exec() then the + * socket will be closed by the operating system. + * + * \warning + * We only make use of the first address found by getaddrinfo(). All + * the other addresses are ignored. + * + * \exception udp_client_server_runtime_error + * The udp_client_server_runtime_error exception is raised when the address + * and port combinaison cannot be resolved or if the socket cannot be + * opened. + * + * \param[in] addr The address we receive on. + * \param[in] port The port we receive from. + */ +UDPServer::UDPServer(const std::string& addr, int port) + : f_port(port) + , f_addr(addr) +{ + char decimal_port[16]; + snprintf(decimal_port, sizeof(decimal_port), "%d", f_port); + decimal_port[sizeof(decimal_port) / sizeof(decimal_port[0]) - 1] = '\0'; + struct addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + int r(getaddrinfo(addr.c_str(), decimal_port, &hints, &f_addrinfo)); + if(r != 0 || f_addrinfo == NULL) + { + throw udp_client_server_runtime_error(("invalid address or port for UDP socket: \"" + addr + ":" + decimal_port + "\"").c_str()); + } + f_socket = socket(f_addrinfo->ai_family, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP); + if(f_socket == -1) + { + freeaddrinfo(f_addrinfo); + throw udp_client_server_runtime_error(("could not create UDP socket for: \"" + addr + ":" + decimal_port + "\"").c_str()); + } + r = bind(f_socket, f_addrinfo->ai_addr, f_addrinfo->ai_addrlen); + if(r != 0) + { + freeaddrinfo(f_addrinfo); + close(f_socket); + throw udp_client_server_runtime_error(("could not bind UDP socket with: \"" + addr + ":" + decimal_port + "\"").c_str()); + } +} + +/** \brief Clean up the UDP server. + * + * This function frees the address info structures and close the socket. + */ +UDPServer::~UDPServer() +{ + freeaddrinfo(f_addrinfo); + close(f_socket); +} + +/** \brief The socket used by this UDP server. + * + * This function returns the socket identifier. It can be useful if you are + * doing a select() on many sockets. + * + * \return The socket of this UDP server. + */ +int UDPServer::get_socket() const +{ + return f_socket; +} + +/** \brief The port used by this UDP server. + * + * This function returns the port attached to the UDP server. It is a copy + * of the port specified in the constructor. + * + * \return The port of the UDP server. + */ +int UDPServer::get_port() const +{ + return f_port; +} + +/** \brief Return the address of this UDP server. + * + * This function returns a verbatim copy of the address as passed to the + * constructor of the UDP server (i.e. it does not return the canonalized + * version of the address.) + * + * \return The address as passed to the constructor. + */ +std::string UDPServer::get_addr() const +{ + return f_addr; +} + +/** \brief Wait on a message. + * + * This function waits until a message is received on this UDP server. + * There are no means to return from this function except by receiving + * a message. Remember that UDP does not have a connect state so whether + * another process quits does not change the status of this UDP server + * and thus it continues to wait forever. + * + * Note that you may change the type of socket by making it non-blocking + * (use the get_socket() to retrieve the socket identifier) in which + * case this function will not block if no message is available. Instead + * it returns immediately. + * + * \param[in] msg The buffer where the message is saved. + * \param[in] max_size The maximum size the message (i.e. size of the \p msg buffer.) + * + * \return The number of bytes read or -1 if an error occurs. + */ +int UDPServer::recv(char *msg, size_t max_size) +{ + return ::recv(f_socket, msg, max_size, 0); +} + +/** \brief Wait for data to come in. + * + * This function waits for a given amount of time for data to come in. If + * no data comes in after max_wait_ms, the function returns with -1 and + * errno set to EAGAIN. + * + * The socket is expected to be a blocking socket (the default,) although + * it is possible to setup the socket as non-blocking if necessary for + * some other reason. + * + * This function blocks for a maximum amount of time as defined by + * max_wait_ms. It may return sooner with an error or a message. + * + * \param[in] msg The buffer where the message will be saved. + * \param[in] max_size The size of the \p msg buffer in bytes. + * \param[in] max_wait_ms The maximum number of milliseconds to wait for a message. + * + * \return -1 if an error occurs or the function timed out, the number of bytes received otherwise. + */ +int UDPServer::timed_recv(char *msg, size_t max_size, int max_wait_ms) +{ + fd_set s; + FD_ZERO(&s); + FD_SET(f_socket, &s); + struct timeval timeout; + timeout.tv_sec = max_wait_ms / 1000; + timeout.tv_usec = (max_wait_ms % 1000) * 1000; + int retval = select(f_socket + 1, &s, &s, &s, &timeout); + if(retval == -1) + { + // select() set errno accordingly + return -1; + } + if(retval > 0) + { + // our socket has data + return ::recv(f_socket, msg, max_size, 0); + } + + // our socket has no data + errno = EAGAIN; + return -1; +} diff --git a/src/UDPServer/UDPServer.h b/src/UDPServer/UDPServer.h new file mode 100644 index 0000000..7eef796 --- /dev/null +++ b/src/UDPServer/UDPServer.h @@ -0,0 +1,39 @@ +/* + * http://linux.m2osw.com/c-implementation-udp-clientserver + * + * UDPServer.h + * + * Created on: 29.06.2016 + * Author: Tobias Frust + */ + +#ifndef UDPSERVER_H_ +#define UDPSERVER_H_ + +#include +#include +#include +#include +#include + +class UDPServer +{ +public: + UDPServer(const std::string& addr, int port); + ~UDPServer(); + + int get_socket() const; + int get_port() const; + std::string get_addr() const; + + int recv(char *msg, size_t max_size); + int timed_recv(char *msg, size_t max_size, int max_wait_ms); + +private: + int f_socket; + int f_port; + std::string f_addr; + struct addrinfo * f_addrinfo; +}; + +#endif /* UDPSERVER_H_ */ diff --git a/src/main.cpp b/src/main.cpp index e69de29..2ff08b2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -0,0 +1,22 @@ +#include "UDPClient/UDPClient.h" + +#include +#include + +int main (int argc, char *argv[]){ + + std::cout << "Sending UDP packages: " << std::endl; + + std::string address = "192.168.178.33"; + int port = 1234; + + UDPClient client = UDPClient(address, port); + + std::string msg = "test"; + std::size_t length{msg.size()}; + + client.send(msg.c_str(), length); + + return 0; + +} -- cgit v1.2.1 From 1dc95b4eed7974549ef43a87e0777aa343b30fd4 Mon Sep 17 00:00:00 2001 From: Tobias Frust Date: Wed, 29 Jun 2016 21:44:58 +0200 Subject: added client and server executable for testing simple udp packet transfer --- src/CMakeLists.txt | 10 ++++++++-- src/UDPServer/UDPServer.cpp | 10 ++++++++++ src/UDPServer/UDPServer.h | 8 +++++++- src/main.cpp | 11 ++++++++--- src/main_server.cpp | 28 ++++++++++++++++++++++++++++ 5 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 src/main_server.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 746b901..80196d9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -31,11 +31,17 @@ include_directories( ${BOOST_INCLUDE_DIRS} ) -set(SOURCES +set(SOURCES_CLIENT "${CMAKE_SOURCE_DIR}/UDPClient/UDPClient.cpp" "${CMAKE_SOURCE_DIR}/main.cpp" ) -add_executable(onlineDetectorSimulator ${SOURCES}) +set(SOURCES_SERVER + "${CMAKE_SOURCE_DIR}/UDPServer/UDPServer.cpp" + "${CMAKE_SOURCE_DIR}/main_server.cpp" +) + +add_executable(onlineDetectorSimulatorServer ${SOURCES_SERVER}) +add_executable(onlineDetectorSimulatorClient ${SOURCES_CLIENT}) diff --git a/src/UDPServer/UDPServer.cpp b/src/UDPServer/UDPServer.cpp index cd36647..854835a 100644 --- a/src/UDPServer/UDPServer.cpp +++ b/src/UDPServer/UDPServer.cpp @@ -41,6 +41,16 @@ * \param[in] addr The address we receive on. * \param[in] port The port we receive from. */ + +#include "UDPServer.h" + + #include + #include + + #ifndef SOCK_CLOEXEC + #define SOCK_CLOEXEC 0 + #endif + UDPServer::UDPServer(const std::string& addr, int port) : f_port(port) , f_addr(addr) diff --git a/src/UDPServer/UDPServer.h b/src/UDPServer/UDPServer.h index 7eef796..22f33b3 100644 --- a/src/UDPServer/UDPServer.h +++ b/src/UDPServer/UDPServer.h @@ -14,7 +14,13 @@ #include #include #include -#include +#include + +class udp_client_server_runtime_error : public std::runtime_error +{ +public: + udp_client_server_runtime_error(const char *w) : std::runtime_error(w) {} +}; class UDPServer { diff --git a/src/main.cpp b/src/main.cpp index 2ff08b2..6898a09 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -12,10 +12,15 @@ int main (int argc, char *argv[]){ UDPClient client = UDPClient(address, port); - std::string msg = "test"; - std::size_t length{msg.size()}; + std::size_t length{8008}; - client.send(msg.c_str(), length); + char buf[length]; + for(auto i = 0; i < length; i++){ + *(buf+i) = i%128; + } + + + client.send(buf, length); return 0; diff --git a/src/main_server.cpp b/src/main_server.cpp new file mode 100644 index 0000000..b90de52 --- /dev/null +++ b/src/main_server.cpp @@ -0,0 +1,28 @@ +#include "UDPServer/UDPServer.h" + +#include +#include + +int main (int argc, char *argv[]){ + + std::cout << "Receiving UDP packages: " << std::endl; + + std::string address = "localhost"; + int port = 1234; + + UDPServer server = UDPServer(address, port); + + std::size_t length{8000}; + + char buf[length]; + + server.recv(buf, length); + + for(auto i = 0; i < length; i++){ + printf("%c", buf[i]); + } + printf("\n"); + + return 0; + +} -- cgit v1.2.1 From 5680aa99001cb50c707c4187cd8ada0c41a573dd Mon Sep 17 00:00:00 2001 From: Tobias Frust Date: Thu, 30 Jun 2016 10:13:01 +0200 Subject: implemented virtual DetectorModule with simple send via udp --- src/CMakeLists.txt | 10 +++++- src/CMakeLists.txt~ | 13 ++++++-- src/ConfigReader/ConfigReader.cpp | 25 +++++++++++++++ src/ConfigReader/ConfigReader.h | 48 ++++++++++++++++++++++++++++ src/Detector/Detector.cpp | 12 +++++++ src/Detector/Detector.h | 15 +++++++++ src/DetectorModule/DetectorModule.cpp | 60 +++++++++++++++++++++++++++++++++++ src/DetectorModule/DetectorModule.h | 39 +++++++++++++++++++++-- src/main.cpp | 27 ---------------- src/main_client.cpp | 20 ++++++++++++ src/main_server.cpp | 12 +++---- 11 files changed, 243 insertions(+), 38 deletions(-) create mode 100644 src/ConfigReader/ConfigReader.cpp create mode 100644 src/ConfigReader/ConfigReader.h create mode 100644 src/Detector/Detector.cpp create mode 100644 src/Detector/Detector.h delete mode 100644 src/main.cpp create mode 100644 src/main_client.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 80196d9..8e2b5f4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -31,9 +31,16 @@ include_directories( ${BOOST_INCLUDE_DIRS} ) +set(LINK_LIBRARIES ${LINK_LIBRARIES} + ${LIBCONFIGPP_LIBRARY} + ${Boost_LIBRARIES} +) + set(SOURCES_CLIENT + "${CMAKE_SOURCE_DIR}/ConfigReader/ConfigReader.cpp" "${CMAKE_SOURCE_DIR}/UDPClient/UDPClient.cpp" - "${CMAKE_SOURCE_DIR}/main.cpp" + "${CMAKE_SOURCE_DIR}/DetectorModule/DetectorModule.cpp" + "${CMAKE_SOURCE_DIR}/main_client.cpp" ) set(SOURCES_SERVER @@ -43,5 +50,6 @@ set(SOURCES_SERVER add_executable(onlineDetectorSimulatorServer ${SOURCES_SERVER}) add_executable(onlineDetectorSimulatorClient ${SOURCES_CLIENT}) +target_link_libraries(onlineDetectorSimulatorClient ${LINK_LIBRARIES}) diff --git a/src/CMakeLists.txt~ b/src/CMakeLists.txt~ index 36ea910..80196d9 100644 --- a/src/CMakeLists.txt~ +++ b/src/CMakeLists.txt~ @@ -31,8 +31,17 @@ include_directories( ${BOOST_INCLUDE_DIRS} ) -file(GLOB SOURCES - "*.cpp" +set(SOURCES_CLIENT + "${CMAKE_SOURCE_DIR}/UDPClient/UDPClient.cpp" + "${CMAKE_SOURCE_DIR}/main.cpp" ) +set(SOURCES_SERVER + "${CMAKE_SOURCE_DIR}/UDPServer/UDPServer.cpp" + "${CMAKE_SOURCE_DIR}/main_server.cpp" +) + +add_executable(onlineDetectorSimulatorServer ${SOURCES_SERVER}) +add_executable(onlineDetectorSimulatorClient ${SOURCES_CLIENT}) + diff --git a/src/ConfigReader/ConfigReader.cpp b/src/ConfigReader/ConfigReader.cpp new file mode 100644 index 0000000..7589d6a --- /dev/null +++ b/src/ConfigReader/ConfigReader.cpp @@ -0,0 +1,25 @@ +/* + * ConfigReader.cpp + * + * Created on: 18.04.2016 + * Author: Tobias Frust (t.frust@hzdr.de) + */ + +#include +#include +#include + +#include "ConfigReader.h" + +ConfigReader::ConfigReader(const char* configFile) { + try { + cfg.readFile(configFile); + } catch (const libconfig::FileIOException &fioex) { + std::cerr << "I/O error while reading file." << std::endl; + exit(1); + } catch (const libconfig::ParseException &pex) { + std::cerr << "Parse error at " << pex.getFile() << ":" << pex.getLine() + << " - " << pex.getError() << std::endl; + exit(1); + } +} diff --git a/src/ConfigReader/ConfigReader.h b/src/ConfigReader/ConfigReader.h new file mode 100644 index 0000000..2819f41 --- /dev/null +++ b/src/ConfigReader/ConfigReader.h @@ -0,0 +1,48 @@ +/* + * Copyright 2016 Tobias Frust + * + * ConfigReader.h + * + * Created on: 18.04.2016 + * Author: Tobias Frust (t.frust@hzdr.de) + */ + +#ifndef CONFIGREADER_H +#define CONFIGREADER_H +#pragma once + +#include + +#include + +#include + +class ConfigReader { +public: + ConfigReader(const char* configFile); + ConfigReader(const ConfigReader& configReader) { + } + + template + bool lookupValue(const std::string& identifier, T& value) { + bool ret = cfg.lookupValue(identifier.c_str(), value); + BOOST_LOG_TRIVIAL(debug) << "Configuration value " << identifier << ": " << value; + return ret; + } + + template + bool lookupValue(const std::string& identifier, int index, T& value) { + libconfig::Setting& s = cfg.lookup(identifier.c_str()); + if(s.getLength() > index){ + value = s[index]; + BOOST_LOG_TRIVIAL(debug) << "Configuration value " << identifier << "[" << index << "]: " << value; + return true; + } + return false; + } + +private: + libconfig::Config cfg; +}; + +#endif diff --git a/src/Detector/Detector.cpp b/src/Detector/Detector.cpp new file mode 100644 index 0000000..bc6c0da --- /dev/null +++ b/src/Detector/Detector.cpp @@ -0,0 +1,12 @@ +/* + * Copyright 2016 Tobias Frust + * + * Detector.cpp + * + * Created on: 30.06.2016 + * Author: Tobias Frust + */ + + + + diff --git a/src/Detector/Detector.h b/src/Detector/Detector.h new file mode 100644 index 0000000..17acb8d --- /dev/null +++ b/src/Detector/Detector.h @@ -0,0 +1,15 @@ +/* + * Copyright 2016 Tobias Frust + * + * Detector.h + * + * Created on: 30.06.2016 + * Author: Tobias Frust + */ + +#ifndef DETECTOR_H_ +#define DETECTOR_H_ + + + +#endif /* DETECTOR_H_ */ diff --git a/src/DetectorModule/DetectorModule.cpp b/src/DetectorModule/DetectorModule.cpp index ac9ee27..f0c1a06 100644 --- a/src/DetectorModule/DetectorModule.cpp +++ b/src/DetectorModule/DetectorModule.cpp @@ -7,3 +7,63 @@ * Author: Tobias Frust */ +#include "DetectorModule.h" +#include "../ConfigReader/ConfigReader.h" + +#include +#include + +template +DetectorModule::DetectorModule(const int detectorID, const std::string& address, const std::string& configPath) : + detectorID_{detectorID}, + numberOfDetectorsPerModule_{16}, + index_{0}, + client_{address, detectorID + 4000} { + + if (readConfig(configPath)) { + throw std::runtime_error("DetectorModule: Configuration file could not be loaded successfully. Please check!"); + } + + //read the input data from the file corresponding to the detectorModuleID + readInput(); +} + +template +auto DetectorModule::sendPeriodically(unsigned int timeIntervall) -> void { + client_.send(buffer_.data(), sizeof(T)*numberOfDetectorsPerModule_*numberOfProjections_); +} + +template +auto DetectorModule::readInput() -> void { + if(path_.back() != '/') + path_.append("/"); + //open file + std::ifstream input(path_ + fileName_ + std::to_string(detectorID_) + fileEnding_, std::ios::in | std::ios::binary); + //allocate memory in vector + std::streampos fileSize; + input.seekg(0, std::ios::end); + fileSize = input.tellg(); + input.seekg(0, std::ios::beg); + buffer_.resize(fileSize / sizeof(T)); + input.read((char*) &buffer_[0], fileSize); +} + +template +auto DetectorModule::readConfig(const std::string& configFile) -> bool { + ConfigReader configReader = ConfigReader(configFile.data()); + int samplingRate, scanRate; + if (configReader.lookupValue("numberOfFanDetectors", numberOfDetectors_) + && configReader.lookupValue("dataInputPath", path_) + && configReader.lookupValue("dataFileName", fileName_) + && configReader.lookupValue("dataFileEnding", fileEnding_) + && configReader.lookupValue("numberOfPlanes", numberOfPlanes_) + && configReader.lookupValue("samplingRate", samplingRate) + && configReader.lookupValue("scanRate", scanRate) + && configReader.lookupValue("numberOfDataFrames", numberOfFrames_)) { + numberOfProjections_ = samplingRate * 1000000 / scanRate; + return EXIT_SUCCESS; + } + + return EXIT_FAILURE; + } + diff --git a/src/DetectorModule/DetectorModule.h b/src/DetectorModule/DetectorModule.h index aa63d82..de259fa 100644 --- a/src/DetectorModule/DetectorModule.h +++ b/src/DetectorModule/DetectorModule.h @@ -10,15 +10,50 @@ #ifndef DETECTORMODULE_H_ #define DETECTORMODULE_H_ +#include "../UDPClient/UDPClient.h" + #include +#include +#include +#include +#include + +void timer_start(std::function func, unsigned int interval){ + std::thread([func, interval]() { + while (true) + { + func(); + std::this_thread::sleep_for(std::chrono::milliseconds(interval)); + } + }).detach(); +} + template class DetectorModule { public: - DetectorModule(); + DetectorModule(const int detectorID, const std::string& address, const std::string& configPath); + + auto sendPeriodically(unsigned int timeIntervall) -> void; private: - std::vector> buffer_; + std::vector buffer_; + + int detectorID_; + UDPClient client_; + + int numberOfDetectors_; + int numberOfPlanes_; + int numberOfProjections_; + int numberOfDetectorsPerModule_; + std::size_t numberOfFrames_; + std::string path_, fileName_, fileEnding_; + + std::size_t index_; + + auto readConfig(const std::string& configFile) -> bool; + auto readInput() -> void; + }; #endif diff --git a/src/main.cpp b/src/main.cpp deleted file mode 100644 index 6898a09..0000000 --- a/src/main.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "UDPClient/UDPClient.h" - -#include -#include - -int main (int argc, char *argv[]){ - - std::cout << "Sending UDP packages: " << std::endl; - - std::string address = "192.168.178.33"; - int port = 1234; - - UDPClient client = UDPClient(address, port); - - std::size_t length{8008}; - - char buf[length]; - for(auto i = 0; i < length; i++){ - *(buf+i) = i%128; - } - - - client.send(buf, length); - - return 0; - -} diff --git a/src/main_client.cpp b/src/main_client.cpp new file mode 100644 index 0000000..363f610 --- /dev/null +++ b/src/main_client.cpp @@ -0,0 +1,20 @@ +#include "UDPClient/UDPClient.h" +#include "DetectorModule/DetectorModule.h" + +#include +#include + +int main (int argc, char *argv[]){ + + std::cout << "Sending UDP packages: " << std::endl; + + auto configPath = std::string { "config.cfg" }; + std::string address = "10.0.0.10"; + + DetectorModule detModule0 = DetectorModule(0, address, configPath); + + detModule0.sendPeriodically(5000); + + return 0; + +} diff --git a/src/main_server.cpp b/src/main_server.cpp index b90de52..267023f 100644 --- a/src/main_server.cpp +++ b/src/main_server.cpp @@ -7,19 +7,19 @@ int main (int argc, char *argv[]){ std::cout << "Receiving UDP packages: " << std::endl; - std::string address = "localhost"; - int port = 1234; + std::string address = "10.0.0.10"; + int port = 4000; UDPServer server = UDPServer(address, port); - std::size_t length{8000}; + std::size_t length{16*500}; - char buf[length]; + unsigned short buf[length]; - server.recv(buf, length); + server.recv(buf, length*sizeof(unsigned short)); for(auto i = 0; i < length; i++){ - printf("%c", buf[i]); + printf("%i ", buf[i]); } printf("\n"); -- cgit v1.2.1 From dbf28e725f062744222559257abe64d8a39a9d50 Mon Sep 17 00:00:00 2001 From: Tobias Frust Date: Thu, 30 Jun 2016 10:27:20 +0200 Subject: bug fixes --- src/DetectorModule/DetectorModule.cpp | 16 ++++++---------- src/DetectorModule/DetectorModule.h | 25 ++++++++++++------------- src/UDPClient/UDPClient.cpp | 2 +- src/main_client.cpp | 4 ++-- src/main_server.cpp | 2 +- 5 files changed, 22 insertions(+), 27 deletions(-) diff --git a/src/DetectorModule/DetectorModule.cpp b/src/DetectorModule/DetectorModule.cpp index f0c1a06..d2c8298 100644 --- a/src/DetectorModule/DetectorModule.cpp +++ b/src/DetectorModule/DetectorModule.cpp @@ -13,8 +13,7 @@ #include #include -template -DetectorModule::DetectorModule(const int detectorID, const std::string& address, const std::string& configPath) : +DetectorModule::DetectorModule(const int detectorID, const std::string& address, const std::string& configPath) : detectorID_{detectorID}, numberOfDetectorsPerModule_{16}, index_{0}, @@ -28,13 +27,11 @@ DetectorModule::DetectorModule(const int detectorID, const std::string& addre readInput(); } -template -auto DetectorModule::sendPeriodically(unsigned int timeIntervall) -> void { - client_.send(buffer_.data(), sizeof(T)*numberOfDetectorsPerModule_*numberOfProjections_); +auto DetectorModule::sendPeriodically(unsigned int timeIntervall) -> void { + client_.send((char*)buffer_.data(), sizeof(unsigned short)*numberOfDetectorsPerModule_*numberOfProjections_); } -template -auto DetectorModule::readInput() -> void { +auto DetectorModule::readInput() -> void { if(path_.back() != '/') path_.append("/"); //open file @@ -44,12 +41,11 @@ auto DetectorModule::readInput() -> void { input.seekg(0, std::ios::end); fileSize = input.tellg(); input.seekg(0, std::ios::beg); - buffer_.resize(fileSize / sizeof(T)); + buffer_.resize(fileSize / sizeof(unsigned short)); input.read((char*) &buffer_[0], fileSize); } -template -auto DetectorModule::readConfig(const std::string& configFile) -> bool { +auto DetectorModule::readConfig(const std::string& configFile) -> bool { ConfigReader configReader = ConfigReader(configFile.data()); int samplingRate, scanRate; if (configReader.lookupValue("numberOfFanDetectors", numberOfDetectors_) diff --git a/src/DetectorModule/DetectorModule.h b/src/DetectorModule/DetectorModule.h index de259fa..a1c2754 100644 --- a/src/DetectorModule/DetectorModule.h +++ b/src/DetectorModule/DetectorModule.h @@ -19,17 +19,16 @@ #include #include -void timer_start(std::function func, unsigned int interval){ - std::thread([func, interval]() { - while (true) - { - func(); - std::this_thread::sleep_for(std::chrono::milliseconds(interval)); - } - }).detach(); -} - -template +//void timer_start(std::function func, unsigned int interval){ +// std::thread([func, interval]() { +// while (true) +// { +// func(); +// std::this_thread::sleep_for(std::chrono::milliseconds(interval)); +// } +// }).detach(); +//} + class DetectorModule { public: DetectorModule(const int detectorID, const std::string& address, const std::string& configPath); @@ -37,7 +36,7 @@ public: auto sendPeriodically(unsigned int timeIntervall) -> void; private: - std::vector buffer_; + std::vector buffer_; int detectorID_; UDPClient client_; @@ -46,7 +45,7 @@ private: int numberOfPlanes_; int numberOfProjections_; int numberOfDetectorsPerModule_; - std::size_t numberOfFrames_; + unsigned long long numberOfFrames_; std::string path_, fileName_, fileEnding_; std::size_t index_; diff --git a/src/UDPClient/UDPClient.cpp b/src/UDPClient/UDPClient.cpp index 75e81e1..844b7f9 100644 --- a/src/UDPClient/UDPClient.cpp +++ b/src/UDPClient/UDPClient.cpp @@ -135,6 +135,6 @@ * \return -1 if an error occurs, otherwise the number of bytes sent. errno * is set accordingly on error. */ - int UDPClient::send(const char *msg, size_t size){ + int UDPClient::send(const char *msg, std::size_t size){ return sendto(f_socket, msg, size, 0, f_addrinfo->ai_addr, f_addrinfo->ai_addrlen); } diff --git a/src/main_client.cpp b/src/main_client.cpp index 363f610..451bd02 100644 --- a/src/main_client.cpp +++ b/src/main_client.cpp @@ -11,9 +11,9 @@ int main (int argc, char *argv[]){ auto configPath = std::string { "config.cfg" }; std::string address = "10.0.0.10"; - DetectorModule detModule0 = DetectorModule(0, address, configPath); + DetectorModule detModule0 = DetectorModule(0, address, configPath); - detModule0.sendPeriodically(5000); + detModule0.sendPeriodically(5000u); return 0; diff --git a/src/main_server.cpp b/src/main_server.cpp index 267023f..167dfca 100644 --- a/src/main_server.cpp +++ b/src/main_server.cpp @@ -16,7 +16,7 @@ int main (int argc, char *argv[]){ unsigned short buf[length]; - server.recv(buf, length*sizeof(unsigned short)); + server.recv((char *)buf, length*sizeof(unsigned short)); for(auto i = 0; i < length; i++){ printf("%i ", buf[i]); -- cgit v1.2.1 From 0c33319451deec9b5461b57856423bc619817245 Mon Sep 17 00:00:00 2001 From: Tobias Frust Date: Thu, 30 Jun 2016 15:22:07 +0200 Subject: added classes for detector; Sending out in n different streams with n different ports --- src/CMakeLists.txt | 3 +- src/Detector/Detector.cpp | 14 ++++++++ src/Detector/Detector.h | 20 +++++++++++ src/DetectorModule/DetectorModule.cpp | 62 +++++++++++++++++++++++++++++------ src/DetectorModule/DetectorModule.h | 14 ++------ src/UDPClient/UDPClient.cpp | 2 ++ src/UDPServer/UDPServer.cpp | 10 +++--- src/main_client.cpp | 25 ++++++++++++-- src/main_server.cpp | 56 ++++++++++++++++++++++++------- 9 files changed, 164 insertions(+), 42 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8e2b5f4..d77a039 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -40,6 +40,7 @@ set(SOURCES_CLIENT "${CMAKE_SOURCE_DIR}/ConfigReader/ConfigReader.cpp" "${CMAKE_SOURCE_DIR}/UDPClient/UDPClient.cpp" "${CMAKE_SOURCE_DIR}/DetectorModule/DetectorModule.cpp" + "${CMAKE_SOURCE_DIR}/Detector/Detector.cpp" "${CMAKE_SOURCE_DIR}/main_client.cpp" ) @@ -51,5 +52,5 @@ set(SOURCES_SERVER add_executable(onlineDetectorSimulatorServer ${SOURCES_SERVER}) add_executable(onlineDetectorSimulatorClient ${SOURCES_CLIENT}) target_link_libraries(onlineDetectorSimulatorClient ${LINK_LIBRARIES}) - +target_link_libraries(onlineDetectorSimulatorServer ${LINK_LIBRARIES}) diff --git a/src/Detector/Detector.cpp b/src/Detector/Detector.cpp index bc6c0da..658f485 100644 --- a/src/Detector/Detector.cpp +++ b/src/Detector/Detector.cpp @@ -8,5 +8,19 @@ */ +#include "Detector.h" +Detector::Detector(const std::string& address, const std::string& configPath, const unsigned int timeIntervall) : + timeIntervall_{timeIntervall}, + numberOfDetectorModules_{27} { + modules_.reserve(numberOfDetectorModules_); + for(auto i = 1; i <= numberOfDetectorModules_; i++){ + modules_.emplace_back(i, address, configPath); + } +} + +auto Detector::run() -> void { + for(auto i = 0; i < numberOfDetectorModules_; i++) + modules_[i].sendPeriodically(timeIntervall_); +} diff --git a/src/Detector/Detector.h b/src/Detector/Detector.h index 17acb8d..1969dbd 100644 --- a/src/Detector/Detector.h +++ b/src/Detector/Detector.h @@ -10,6 +10,26 @@ #ifndef DETECTOR_H_ #define DETECTOR_H_ +#include "../DetectorModule/DetectorModule.h" +#include +#include + +class Detector { +public: + Detector(const std::string& address, const std::string& configPath, const unsigned int timeIntervall); + + auto run() -> void; +private: + std::vector modules_; + + std::vector moduleThreads_; + + unsigned int timeIntervall_; + int numberOfDetectorModules_; + + auto readConfig(const std::string& configFile) -> bool; + +}; #endif /* DETECTOR_H_ */ diff --git a/src/DetectorModule/DetectorModule.cpp b/src/DetectorModule/DetectorModule.cpp index d2c8298..789ac0e 100644 --- a/src/DetectorModule/DetectorModule.cpp +++ b/src/DetectorModule/DetectorModule.cpp @@ -10,39 +10,81 @@ #include "DetectorModule.h" #include "../ConfigReader/ConfigReader.h" +#include + #include #include +void timer_start(std::function func, unsigned int interval){ + std::thread([func, interval]() { + while (true) + { + func(); + std::this_thread::sleep_for(std::chrono::microseconds(interval)); + } + }).detach(); +} + DetectorModule::DetectorModule(const int detectorID, const std::string& address, const std::string& configPath) : detectorID_{detectorID}, numberOfDetectorsPerModule_{16}, index_{0}, - client_{address, detectorID + 4000} { + client_{address, detectorID+4000} { + + printf("Creating %d\n", detectorID); if (readConfig(configPath)) { throw std::runtime_error("DetectorModule: Configuration file could not be loaded successfully. Please check!"); } + sendBuffer_.resize(numberOfDetectorsPerModule_*numberOfProjections_*sizeof(unsigned short) + sizeof(std::size_t)); + //read the input data from the file corresponding to the detectorModuleID readInput(); + printf("Created %d\n", detectorID); +} + +auto DetectorModule::send() -> void{ + BOOST_LOG_TRIVIAL(debug) << "Detectormodule " << detectorID_ << " :sending udp packet with index " << index_ << "."; +// sendBuffer_[0] = (sizeof(std::size_t)) & 0xff; +// sendBuffer_[1] = (sizeof(std::size_t) >> 8) & 0xff; +// sendBuffer_[2] = (sizeof(std::size_t) >> 16) & 0xff; +// sendBuffer_[3] = (sizeof(std::size_t) >> 24) & 0xff; +// sendBuffer_[4] = (sizeof(std::size_t) >> 32) & 0xff; +// sendBuffer_[5] = (sizeof(std::size_t) >> 40) & 0xff; +// sendBuffer_[6] = (sizeof(std::size_t) >> 48) & 0xff; +// sendBuffer_[7] = (sizeof(std::size_t) >> 56) & 0xff; + *reinterpret_cast(sendBuffer_.data()) = index_; + std::copy(buffer_.cbegin(), buffer_.cbegin()+numberOfDetectorsPerModule_*numberOfProjections_, sendBuffer_.begin()+sizeof(std::size_t)); + client_.send(sendBuffer_.data(), sizeof(unsigned short)*numberOfDetectorsPerModule_*numberOfProjections_+sizeof(std::size_t)); + ++index_; } auto DetectorModule::sendPeriodically(unsigned int timeIntervall) -> void { - client_.send((char*)buffer_.data(), sizeof(unsigned short)*numberOfDetectorsPerModule_*numberOfProjections_); + std::function f = [=]() { + this->send(); + }; + timer_start(f, timeIntervall); } auto DetectorModule::readInput() -> void { if(path_.back() != '/') path_.append("/"); //open file - std::ifstream input(path_ + fileName_ + std::to_string(detectorID_) + fileEnding_, std::ios::in | std::ios::binary); - //allocate memory in vector - std::streampos fileSize; - input.seekg(0, std::ios::end); - fileSize = input.tellg(); - input.seekg(0, std::ios::beg); - buffer_.resize(fileSize / sizeof(unsigned short)); - input.read((char*) &buffer_[0], fileSize); + const std::string filePath = path_ + fileName_ + std::to_string(detectorID_) + fileEnding_; + BOOST_LOG_TRIVIAL(debug) << "DetectorModule: Path = " << filePath; + std::ifstream input(filePath, std::ios::in | std::ios::binary); + if(input){ + //allocate memory in vector + std::streampos fileSize; + input.seekg(0, std::ios::end); + fileSize = input.tellg(); + input.seekg(0, std::ios::beg); + buffer_.resize(fileSize / sizeof(unsigned short)); + input.read((char*) &buffer_[0], fileSize); + }else{ + throw std::runtime_error("File not found."); + } } auto DetectorModule::readConfig(const std::string& configFile) -> bool { diff --git a/src/DetectorModule/DetectorModule.h b/src/DetectorModule/DetectorModule.h index a1c2754..1bc36bb 100644 --- a/src/DetectorModule/DetectorModule.h +++ b/src/DetectorModule/DetectorModule.h @@ -19,16 +19,6 @@ #include #include -//void timer_start(std::function func, unsigned int interval){ -// std::thread([func, interval]() { -// while (true) -// { -// func(); -// std::this_thread::sleep_for(std::chrono::milliseconds(interval)); -// } -// }).detach(); -//} - class DetectorModule { public: DetectorModule(const int detectorID, const std::string& address, const std::string& configPath); @@ -37,6 +27,7 @@ public: private: std::vector buffer_; + std::vector sendBuffer_; int detectorID_; UDPClient client_; @@ -45,13 +36,14 @@ private: int numberOfPlanes_; int numberOfProjections_; int numberOfDetectorsPerModule_; - unsigned long long numberOfFrames_; + unsigned int numberOfFrames_; std::string path_, fileName_, fileEnding_; std::size_t index_; auto readConfig(const std::string& configFile) -> bool; auto readInput() -> void; + auto send() -> void; }; diff --git a/src/UDPClient/UDPClient.cpp b/src/UDPClient/UDPClient.cpp index 844b7f9..1d427ba 100644 --- a/src/UDPClient/UDPClient.cpp +++ b/src/UDPClient/UDPClient.cpp @@ -50,6 +50,7 @@ UDPClient::UDPClient(const std::string& addr, int port) : f_port(port) , f_addr(addr){ + printf("Creating client %d\n", f_port); char decimal_port[16]; snprintf(decimal_port, sizeof(decimal_port), "%d", f_port); decimal_port[sizeof(decimal_port) / sizeof(decimal_port[0]) - 1] = '\0'; @@ -69,6 +70,7 @@ freeaddrinfo(f_addrinfo); throw udp_client_server_runtime_error(("could not create socket for: \"" + addr + ":" + decimal_port + "\"").c_str()); } + printf("Created client %d\n", f_port); } /** \brief Clean up the UDP client object. diff --git a/src/UDPServer/UDPServer.cpp b/src/UDPServer/UDPServer.cpp index 854835a..3a50d0c 100644 --- a/src/UDPServer/UDPServer.cpp +++ b/src/UDPServer/UDPServer.cpp @@ -44,12 +44,12 @@ #include "UDPServer.h" - #include - #include +#include +#include - #ifndef SOCK_CLOEXEC - #define SOCK_CLOEXEC 0 - #endif +#ifndef SOCK_CLOEXEC +#define SOCK_CLOEXEC 0 +#endif UDPServer::UDPServer(const std::string& addr, int port) : f_port(port) diff --git a/src/main_client.cpp b/src/main_client.cpp index 451bd02..ed7d285 100644 --- a/src/main_client.cpp +++ b/src/main_client.cpp @@ -1,19 +1,38 @@ #include "UDPClient/UDPClient.h" #include "DetectorModule/DetectorModule.h" +#include "Detector/Detector.h" + +#include +#include +#include #include #include +void initLog() { +#ifndef NDEBUG + boost::log::core::get()->set_filter(boost::log::trivial::severity >= boost::log::trivial::debug); +#else + boost::log::core::get()->set_filter(boost::log::trivial::severity >= boost::log::trivial::info); +#endif +} + int main (int argc, char *argv[]){ + initLog(); + std::cout << "Sending UDP packages: " << std::endl; auto configPath = std::string { "config.cfg" }; - std::string address = "10.0.0.10"; + std::string address = "localhost"; + + Detector detector{address, configPath, 1000u}; + + //DetectorModule detModule0 = DetectorModule(1, address, configPath); - DetectorModule detModule0 = DetectorModule(0, address, configPath); + detector.run(); - detModule0.sendPeriodically(5000u); + std::cin.ignore(); return 0; diff --git a/src/main_server.cpp b/src/main_server.cpp index 167dfca..a645f49 100644 --- a/src/main_server.cpp +++ b/src/main_server.cpp @@ -1,28 +1,60 @@ #include "UDPServer/UDPServer.h" +#include +#include +#include + #include #include +#include + +void initLog() { +#ifndef NDEBUG + boost::log::core::get()->set_filter(boost::log::trivial::severity >= boost::log::trivial::debug); +#else + boost::log::core::get()->set_filter(boost::log::trivial::severity >= boost::log::trivial::info); +#endif +} + +void start(std::function func){ + std::thread([func]() { + while (true) + { + func(); + } + }).detach(); +} int main (int argc, char *argv[]){ - std::cout << "Receiving UDP packages: " << std::endl; + initLog(); + + std::string address = "localhost"; + int port = 4002; + + UDPServer server = UDPServer(address, port); - std::string address = "10.0.0.10"; - int port = 4000; + std::size_t length{32768}; - UDPServer server = UDPServer(address, port); + std::vector buf(16000); - std::size_t length{16*500}; + std::cout << "Receiving UDP packages: " << std::endl; - unsigned short buf[length]; +// for(auto i = 0; i < 27; i++){ +// std::function f = [=]() { +// server.recv(); +// }; +// start(); +// } - server.recv((char *)buf, length*sizeof(unsigned short)); + while(true){ + int bytes = server.recv((char*)buf.data(), length); + std::size_t index = *((std::size_t *)buf.data()); + if(index%1000 == 99) printf("%lu\n", index); - for(auto i = 0; i < length; i++){ - printf("%i ", buf[i]); - } - printf("\n"); + BOOST_LOG_TRIVIAL(debug) << "Server: Received " << bytes << " Bytes with Index " << index; + } - return 0; + return 0; } -- cgit v1.2.1 From d71e5fe7330fa51cdce466ec0df876eb9b8e721e Mon Sep 17 00:00:00 2001 From: Tobias Frust Date: Mon, 11 Jul 2016 14:58:00 +0200 Subject: UDP packets are sent out correctly --- src/Detector/Detector.cpp | 2 +- src/DetectorModule/DetectorModule.cpp | 36 ++++++++++++++++++----------------- src/main_client.cpp | 4 ++-- src/main_server.cpp | 6 ++++++ 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/src/Detector/Detector.cpp b/src/Detector/Detector.cpp index 658f485..5dde6d1 100644 --- a/src/Detector/Detector.cpp +++ b/src/Detector/Detector.cpp @@ -14,7 +14,7 @@ Detector::Detector(const std::string& address, const std::string& configPath, co timeIntervall_{timeIntervall}, numberOfDetectorModules_{27} { modules_.reserve(numberOfDetectorModules_); - for(auto i = 1; i <= numberOfDetectorModules_; i++){ + for(auto i = 0; i < numberOfDetectorModules_; i++){ modules_.emplace_back(i, address, configPath); } } diff --git a/src/DetectorModule/DetectorModule.cpp b/src/DetectorModule/DetectorModule.cpp index 789ac0e..bee50e9 100644 --- a/src/DetectorModule/DetectorModule.cpp +++ b/src/DetectorModule/DetectorModule.cpp @@ -54,8 +54,10 @@ auto DetectorModule::send() -> void{ // sendBuffer_[5] = (sizeof(std::size_t) >> 40) & 0xff; // sendBuffer_[6] = (sizeof(std::size_t) >> 48) & 0xff; // sendBuffer_[7] = (sizeof(std::size_t) >> 56) & 0xff; + unsigned int bufferSizeIndex = index_ % 1000; + unsigned int sinoSize = numberOfDetectorsPerModule_*numberOfProjections_; *reinterpret_cast(sendBuffer_.data()) = index_; - std::copy(buffer_.cbegin(), buffer_.cbegin()+numberOfDetectorsPerModule_*numberOfProjections_, sendBuffer_.begin()+sizeof(std::size_t)); + std::copy(((char*)buffer_.data())+sinoSize*bufferSizeIndex*sizeof(unsigned short), ((char*)buffer_.data())+(sinoSize*(1+bufferSizeIndex))*sizeof(unsigned short), sendBuffer_.begin()+sizeof(std::size_t)); client_.send(sendBuffer_.data(), sizeof(unsigned short)*numberOfDetectorsPerModule_*numberOfProjections_+sizeof(std::size_t)); ++index_; } @@ -71,7 +73,7 @@ auto DetectorModule::readInput() -> void { if(path_.back() != '/') path_.append("/"); //open file - const std::string filePath = path_ + fileName_ + std::to_string(detectorID_) + fileEnding_; + const std::string filePath = path_ + fileName_ + std::to_string(detectorID_+1) + fileEnding_; BOOST_LOG_TRIVIAL(debug) << "DetectorModule: Path = " << filePath; std::ifstream input(filePath, std::ios::in | std::ios::binary); if(input){ @@ -88,20 +90,20 @@ auto DetectorModule::readInput() -> void { } auto DetectorModule::readConfig(const std::string& configFile) -> bool { - ConfigReader configReader = ConfigReader(configFile.data()); - int samplingRate, scanRate; - if (configReader.lookupValue("numberOfFanDetectors", numberOfDetectors_) - && configReader.lookupValue("dataInputPath", path_) - && configReader.lookupValue("dataFileName", fileName_) - && configReader.lookupValue("dataFileEnding", fileEnding_) - && configReader.lookupValue("numberOfPlanes", numberOfPlanes_) - && configReader.lookupValue("samplingRate", samplingRate) - && configReader.lookupValue("scanRate", scanRate) - && configReader.lookupValue("numberOfDataFrames", numberOfFrames_)) { - numberOfProjections_ = samplingRate * 1000000 / scanRate; - return EXIT_SUCCESS; - } - - return EXIT_FAILURE; + ConfigReader configReader = ConfigReader(configFile.data()); + int samplingRate, scanRate; + if (configReader.lookupValue("numberOfFanDetectors", numberOfDetectors_) + && configReader.lookupValue("dataInputPath", path_) + && configReader.lookupValue("dataFileName", fileName_) + && configReader.lookupValue("dataFileEnding", fileEnding_) + && configReader.lookupValue("numberOfPlanes", numberOfPlanes_) + && configReader.lookupValue("samplingRate", samplingRate) + && configReader.lookupValue("scanRate", scanRate) + && configReader.lookupValue("numberOfDataFrames", numberOfFrames_)) { + numberOfProjections_ = samplingRate * 1000000 / scanRate; + return EXIT_SUCCESS; } + return EXIT_FAILURE; +} + diff --git a/src/main_client.cpp b/src/main_client.cpp index ed7d285..b88341a 100644 --- a/src/main_client.cpp +++ b/src/main_client.cpp @@ -24,9 +24,9 @@ int main (int argc, char *argv[]){ std::cout << "Sending UDP packages: " << std::endl; auto configPath = std::string { "config.cfg" }; - std::string address = "localhost"; + std::string address = "127.0.0.1"; - Detector detector{address, configPath, 1000u}; + Detector detector{address, configPath, 1000000u}; //DetectorModule detModule0 = DetectorModule(1, address, configPath); diff --git a/src/main_server.cpp b/src/main_server.cpp index a645f49..6e936e4 100644 --- a/src/main_server.cpp +++ b/src/main_server.cpp @@ -35,6 +35,7 @@ int main (int argc, char *argv[]){ UDPServer server = UDPServer(address, port); std::size_t length{32768}; + std::size_t lastIndex{0}; std::vector buf(16000); @@ -52,6 +53,11 @@ int main (int argc, char *argv[]){ std::size_t index = *((std::size_t *)buf.data()); if(index%1000 == 99) printf("%lu\n", index); + if(lastIndex != (index-1)) + BOOST_LOG_TRIVIAL(warning) << "Packet loss or wrong order!"; + + lastIndex = index; + BOOST_LOG_TRIVIAL(debug) << "Server: Received " << bytes << " Bytes with Index " << index; } -- cgit v1.2.1 From 409e2fd20af5620066796e43410a92521376b2c1 Mon Sep 17 00:00:00 2001 From: Tobias Frust Date: Mon, 11 Jul 2016 15:13:55 +0200 Subject: the number of images per second is now configurable via terminal input --- src/main_client.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/main_client.cpp b/src/main_client.cpp index b88341a..2b9927d 100644 --- a/src/main_client.cpp +++ b/src/main_client.cpp @@ -19,6 +19,16 @@ void initLog() { int main (int argc, char *argv[]){ + if(argc < 2){ + BOOST_LOG_TRIVIAL(error) << "Program usage: ./onlineDetectorSimulatorClient !"; + return 0; + } + + int imagesPerSec = std::stoi(argv[1]); + + double timegap = 1./(double)imagesPerSec; + unsigned int intervall = timegap*1000*1000; + initLog(); std::cout << "Sending UDP packages: " << std::endl; @@ -26,7 +36,7 @@ int main (int argc, char *argv[]){ auto configPath = std::string { "config.cfg" }; std::string address = "127.0.0.1"; - Detector detector{address, configPath, 1000000u}; + Detector detector{address, configPath, intervall}; //DetectorModule detModule0 = DetectorModule(1, address, configPath); -- cgit v1.2.1