mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2025-06-13 05:17:13 +02:00
merging refactor (replacing)
This commit is contained in:
42
slsSupportLib/src/ClientInterface.cpp
Executable file
42
slsSupportLib/src/ClientInterface.cpp
Executable file
@ -0,0 +1,42 @@
|
||||
#include "ClientInterface.h"
|
||||
#include "ClientSocket.h"
|
||||
|
||||
ClientInterface::ClientInterface(sls::ClientSocket *socket, int n) : socket_(socket){}
|
||||
|
||||
void ClientInterface::Client_Receive(int &ret, char *mess, void *retval, int sizeOfRetval) {
|
||||
// get result of operation
|
||||
socket_->receiveData(reinterpret_cast<char *>(&ret), sizeof(ret));
|
||||
|
||||
bool unrecognizedFunction = false;
|
||||
if (ret == FAIL) {
|
||||
bool created = false;
|
||||
// allocate mess if null
|
||||
if (!mess) {
|
||||
created = true;
|
||||
mess = new char[MAX_STR_LENGTH];
|
||||
memset(mess, 0, MAX_STR_LENGTH);
|
||||
}
|
||||
// get error message
|
||||
socket_->receiveData(mess, MAX_STR_LENGTH);
|
||||
// cprintf(RED, "%s %d returned error: %s", type.c_str(), index, mess);
|
||||
|
||||
// unrecognized function, do not ask for retval
|
||||
if (strstr(mess, "Unrecognized Function") != nullptr)
|
||||
unrecognizedFunction = true;
|
||||
// delete allocated mess
|
||||
if (created)
|
||||
delete[] mess;
|
||||
}
|
||||
// get retval
|
||||
if (!unrecognizedFunction)
|
||||
socket_->receiveData(reinterpret_cast<char *>(retval), sizeOfRetval);
|
||||
}
|
||||
|
||||
int ClientInterface::Client_Send(int fnum, void *args, int sizeOfArgs, void *retval,
|
||||
int sizeOfRetval, char *mess) {
|
||||
int ret = FAIL;
|
||||
socket_->sendData(reinterpret_cast<char *>(&fnum), sizeof(fnum));
|
||||
socket_->sendData(reinterpret_cast<char *>(args), sizeOfArgs);
|
||||
Client_Receive(ret, mess, retval, sizeOfRetval);
|
||||
return ret;
|
||||
}
|
89
slsSupportLib/src/ClientSocket.cpp
Executable file
89
slsSupportLib/src/ClientSocket.cpp
Executable file
@ -0,0 +1,89 @@
|
||||
#include "ClientSocket.h"
|
||||
#include "logger.h"
|
||||
#include "sls_detector_defs.h"
|
||||
#include "sls_detector_exceptions.h"
|
||||
#include <arpa/inet.h>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <unistd.h>
|
||||
namespace sls {
|
||||
|
||||
ClientSocket::ClientSocket(std::string stype, const std::string &host, uint16_t port)
|
||||
: DataSocket(socket(AF_INET, SOCK_STREAM, 0)), socketType(stype) {
|
||||
|
||||
struct addrinfo hints, *result;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_flags |= AI_CANONNAME;
|
||||
|
||||
if (getaddrinfo(host.c_str(), NULL, &hints, &result) != 0) {
|
||||
std::string msg =
|
||||
"ClientSocket cannot decode host:" + host + " on port " + std::to_string(port) + "\n";
|
||||
throw SocketError(msg);
|
||||
}
|
||||
|
||||
// TODO! Erik, results could have multiple entries do we need to loop through them?
|
||||
// struct sockaddr_in serverAddr {};
|
||||
serverAddr.sin_family = AF_INET;
|
||||
serverAddr.sin_port = htons(port);
|
||||
memcpy((char *)&serverAddr.sin_addr.s_addr, &((struct sockaddr_in *)result->ai_addr)->sin_addr,
|
||||
sizeof(in_addr_t));
|
||||
|
||||
if (::connect(getSocketId(), (struct sockaddr *)&serverAddr, sizeof(serverAddr)) != 0) {
|
||||
freeaddrinfo(result);
|
||||
std::string msg = "ClientSocket: Cannot connect to " + socketType + ":" +
|
||||
host + " on port " + std::to_string(port) + "\n";
|
||||
throw SocketError(msg);
|
||||
}
|
||||
freeaddrinfo(result);
|
||||
}
|
||||
|
||||
ClientSocket::ClientSocket(std::string sType, struct sockaddr_in addr)
|
||||
: DataSocket(socket(AF_INET, SOCK_STREAM, 0)), socketType(sType) {
|
||||
|
||||
if (::connect(getSocketId(), (struct sockaddr *)&addr, sizeof(addr)) != 0) {
|
||||
char address[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, &addr.sin_addr, address, INET_ADDRSTRLEN);
|
||||
std::string msg = "ClientSocket: Cannot connect to " + socketType + ":" + address + " on port " +
|
||||
std::to_string(addr.sin_port) + "\n";
|
||||
throw SocketError(msg);
|
||||
}
|
||||
}
|
||||
|
||||
int ClientSocket::sendCommandThenRead(int fnum, void *args, size_t args_size, void *retval,
|
||||
size_t retval_size) {
|
||||
int ret = slsDetectorDefs::FAIL;
|
||||
sendData(&fnum, sizeof(fnum));
|
||||
sendData(args, args_size);
|
||||
readReply(ret, retval, retval_size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ClientSocket::readReply(int &ret, void *retval, size_t retval_size) {
|
||||
|
||||
receiveData(&ret, sizeof(ret));
|
||||
if (ret == slsDetectorDefs::FAIL) {
|
||||
char mess[MAX_STR_LENGTH]{};
|
||||
// get error message
|
||||
receiveData(mess, sizeof(mess));
|
||||
FILE_LOG(logERROR) << socketType << " returned error: " << mess;
|
||||
std::cout << "\n"; // needed to reset the color.
|
||||
|
||||
// Do we need to know hostname here?
|
||||
// In that case save it???
|
||||
if (socketType == "Receiver") {
|
||||
throw ReceiverError(mess);
|
||||
} else if (socketType == "Detector") {
|
||||
throw DetectorError(mess);
|
||||
} else {
|
||||
throw GuiError(mess);
|
||||
}
|
||||
}
|
||||
// get retval
|
||||
receiveData(retval, retval_size);
|
||||
}
|
||||
|
||||
}; // namespace sls
|
84
slsSupportLib/src/CmdLineParser.cpp
Executable file
84
slsSupportLib/src/CmdLineParser.cpp
Executable file
@ -0,0 +1,84 @@
|
||||
|
||||
#include "CmdLineParser.h"
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <sstream>
|
||||
//printing function for debugging
|
||||
void CmdLineParser::Print() {
|
||||
std::cout << "\nCmdLineParser::Print()\n";
|
||||
std::cout << "\tmulti_id: " << multi_id_ << ", detector_id: " << detector_id_ << std::endl;
|
||||
std::cout << "\texecutable: " << executable_ << '\n';
|
||||
std::cout << "\tcommand: " << command_ << '\n';
|
||||
std::cout << "\tn_arguments: " << n_arguments() << '\n';
|
||||
std::cout << "\targuments: ";
|
||||
for (const auto &argument : arguments_) {
|
||||
std::cout << argument << " ";
|
||||
}
|
||||
std::cout << "\n\n";
|
||||
};
|
||||
|
||||
void CmdLineParser::Parse(int argc, char *argv[]) {
|
||||
//first element of argv is the command used to call the executable ->skipping
|
||||
//and if this is the only command skip all
|
||||
executable_ = argv[0];
|
||||
if (argc > 1) {
|
||||
//second element is cmd string that needs to be decoded
|
||||
DecodeIdAndPosition(argv[1]);
|
||||
//The rest of the arguments goes into a vector for later processing
|
||||
for (int i = 2; i < argc; ++i) {
|
||||
arguments_.emplace_back(std::string(argv[i]));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void CmdLineParser::Parse(const std::string &s) {
|
||||
std::istringstream iss(s);
|
||||
auto it = std::istream_iterator<std::string>(iss);
|
||||
//read the first element and increment
|
||||
command_ = *it++;
|
||||
arguments_ = std::vector<std::string>(it, std::istream_iterator<std::string>());
|
||||
;
|
||||
DecodeIdAndPosition(command_.c_str());
|
||||
}
|
||||
|
||||
void CmdLineParser::DecodeIdAndPosition(const char *c) {
|
||||
bool contains_id = std::strchr(c, '-') != nullptr;
|
||||
bool contains_pos = std::strchr(c, ':') != nullptr;
|
||||
char tmp[100];
|
||||
|
||||
if (contains_id && contains_pos) {
|
||||
int r = sscanf(c, "%d-%d:%s", &multi_id_, &detector_id_, tmp);
|
||||
if (r != 3) {
|
||||
throw(std::invalid_argument("Cannot decode client or detector id from: \"" + std::string(c) + "\"\n"));
|
||||
}
|
||||
command_ = tmp;
|
||||
} else if (contains_id && !contains_pos) {
|
||||
int r = sscanf(c, "%d-%s", &multi_id_, tmp);
|
||||
if (r != 2) {
|
||||
throw(std::invalid_argument("Cannot decode client id from: \"" + std::string(c) + "\"\n"));
|
||||
}
|
||||
command_ = tmp;
|
||||
} else if (!contains_id && contains_pos) {
|
||||
int r = sscanf(c, "%d:%s", &detector_id_, tmp);
|
||||
if (r != 2) {
|
||||
throw(std::invalid_argument("Cannot decode detector id from: \"" + std::string(c) + "\"\n"));
|
||||
}
|
||||
command_ = tmp;
|
||||
} else {
|
||||
command_ = c;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<char *> CmdLineParser::argv() {
|
||||
std::vector<char *> vec;
|
||||
if (command_.empty()!=true){
|
||||
vec.push_back(&command_.front());
|
||||
}
|
||||
|
||||
for (auto &arg : arguments_) {
|
||||
vec.push_back(&arg.front());
|
||||
}
|
||||
return vec;
|
||||
}
|
159
slsSupportLib/src/DataSocket.cpp
Executable file
159
slsSupportLib/src/DataSocket.cpp
Executable file
@ -0,0 +1,159 @@
|
||||
#include "DataSocket.h"
|
||||
#include "logger.h"
|
||||
#include "sls_detector_exceptions.h"
|
||||
#include <algorithm>
|
||||
#include <arpa/inet.h>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
namespace sls {
|
||||
|
||||
DataSocket::DataSocket(int socketId) : socketId_(socketId) {}
|
||||
|
||||
DataSocket::~DataSocket() {
|
||||
if (socketId_ <= 0) {
|
||||
return;
|
||||
} else {
|
||||
try {
|
||||
close();
|
||||
} catch (...) {
|
||||
// pass
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DataSocket::swap(DataSocket &other) noexcept { std::swap(socketId_, other.socketId_); }
|
||||
|
||||
DataSocket::DataSocket(DataSocket &&move) noexcept { move.swap(*this); }
|
||||
DataSocket &DataSocket::operator=(DataSocket &&move) noexcept {
|
||||
move.swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_t DataSocket::receiveData(void *buffer, size_t size) {
|
||||
// std::cout << "Sending\n";
|
||||
size_t dataRead = 0;
|
||||
while (dataRead < size) {
|
||||
dataRead +=
|
||||
read(getSocketId(), reinterpret_cast<char *>(buffer) + dataRead, size - dataRead);
|
||||
}
|
||||
return dataRead;
|
||||
}
|
||||
|
||||
size_t DataSocket::sendData(void *buffer, size_t size) {
|
||||
// std::cout << "Receiving\n";
|
||||
size_t dataSent = 0;
|
||||
while (dataSent < size) {
|
||||
dataSent +=
|
||||
write(getSocketId(), reinterpret_cast<char *>(buffer) + dataSent, size - dataSent);
|
||||
}
|
||||
return dataSent;
|
||||
}
|
||||
|
||||
int DataSocket::setTimeOut(int t_seconds) {
|
||||
if (t_seconds <= 0)
|
||||
return -1;
|
||||
|
||||
struct timeval t;
|
||||
t.tv_sec = 0;
|
||||
t.tv_usec = 0;
|
||||
// Receive timeout indefinet
|
||||
if (::setsockopt(getSocketId(), SOL_SOCKET, SO_RCVTIMEO, &t, sizeof(struct timeval)) < 0) {
|
||||
FILE_LOG(logERROR) << "setsockopt SO_RCVTIMEO " << 0;
|
||||
}
|
||||
|
||||
t.tv_sec = t_seconds;
|
||||
t.tv_usec = 0;
|
||||
// Sending timeout in seconds
|
||||
if (::setsockopt(getSocketId(), SOL_SOCKET, SO_SNDTIMEO, &t, sizeof(struct timeval)) < 0) {
|
||||
FILE_LOG(logERROR) << "setsockopt SO_SNDTIMEO " << t_seconds;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DataSocket::close() {
|
||||
if (socketId_ > 0) {
|
||||
if(::close(socketId_)){
|
||||
throw SocketError("could not close socket");
|
||||
}
|
||||
socketId_ = -1;
|
||||
|
||||
} else {
|
||||
throw std::runtime_error("Socket ERROR: close called on bad socket\n");
|
||||
}
|
||||
}
|
||||
|
||||
void DataSocket::shutDownSocket() {
|
||||
shutdown(getSocketId(), SHUT_RDWR);
|
||||
close();
|
||||
}
|
||||
|
||||
struct sockaddr_in ConvertHostnameToInternetAddress(const std::string &hostname) {
|
||||
struct addrinfo hints, *result;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_flags |= AI_CANONNAME;
|
||||
|
||||
struct sockaddr_in serverAddr {};
|
||||
if (getaddrinfo(hostname.c_str(), NULL, &hints, &result) != 0) {
|
||||
freeaddrinfo(result);
|
||||
std::string msg = "ClientSocket cannot decode host:" + hostname + "\n";
|
||||
throw SocketError(msg);
|
||||
}
|
||||
serverAddr.sin_family = AF_INET;
|
||||
memcpy((char *)&serverAddr.sin_addr.s_addr, &((struct sockaddr_in *)result->ai_addr)->sin_addr,
|
||||
sizeof(in_addr_t));
|
||||
freeaddrinfo(result);
|
||||
return serverAddr;
|
||||
}
|
||||
|
||||
int ConvertHostnameToInternetAddress(const char *const hostname, struct ::addrinfo **res) {
|
||||
// criteria in selecting socket address structures returned by res
|
||||
struct ::addrinfo hints;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
// get host info into res
|
||||
int errcode = getaddrinfo(hostname, NULL, &hints, res);
|
||||
if (errcode != 0) {
|
||||
FILE_LOG(logERROR) << "Could not convert hostname (" << hostname
|
||||
<< ") to internet address (zmq):" << gai_strerror(errcode);
|
||||
} else {
|
||||
if (*res == NULL) {
|
||||
FILE_LOG(logERROR) << "Could not converthostname (" << hostname
|
||||
<< ") to internet address (zmq):"
|
||||
"gettaddrinfo returned null";
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
FILE_LOG(logERROR) << "Could not convert hostname to internet address";
|
||||
return 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert Internet Address structure pointer to ip string (char*)
|
||||
* Clears the internet address structure as well
|
||||
* @param res pointer to internet address structure
|
||||
* @param ip pointer to char array to store result in
|
||||
* @param ipsize size available in ip buffer
|
||||
* @return 1 for fail, 0 for success
|
||||
*/
|
||||
// Do not make this static (for multi threading environment)
|
||||
int ConvertInternetAddresstoIpString(struct ::addrinfo *res, char *ip, const int ipsize) {
|
||||
if (inet_ntop(res->ai_family, &((struct sockaddr_in *)res->ai_addr)->sin_addr, ip, ipsize) !=
|
||||
NULL) {
|
||||
::freeaddrinfo(res);
|
||||
return 0;
|
||||
}
|
||||
FILE_LOG(logERROR) << "Could not convert internet address to ip string";
|
||||
return 1;
|
||||
}
|
||||
|
||||
} // namespace sls
|
143
slsSupportLib/src/ServerInterface.cpp
Executable file
143
slsSupportLib/src/ServerInterface.cpp
Executable file
@ -0,0 +1,143 @@
|
||||
#include "ServerInterface.h"
|
||||
|
||||
ServerInterface::ServerInterface(MySocketTCP *socket, int n, std::string t): mySocket(socket),
|
||||
index(n),
|
||||
type(t){}
|
||||
|
||||
void ServerInterface::SetSocket(MySocketTCP *socket) {
|
||||
mySocket = socket;
|
||||
}
|
||||
|
||||
|
||||
void ServerInterface::Client_Receive(int& ret, char* mess, void* retval, int sizeOfRetval) {
|
||||
// get result of operation
|
||||
mySocket->ReceiveDataOnly(&ret,sizeof(ret));
|
||||
|
||||
bool unrecognizedFunction = false;
|
||||
if (ret == FAIL) {
|
||||
bool created = false;
|
||||
// allocate mess if null
|
||||
if (!mess){
|
||||
created = true;
|
||||
mess = new char[MAX_STR_LENGTH];
|
||||
memset(mess, 0, MAX_STR_LENGTH);
|
||||
}
|
||||
// get error message
|
||||
mySocket->ReceiveDataOnly(mess,MAX_STR_LENGTH);
|
||||
cprintf(RED, "%s %d returned error: %s", type.c_str(), index, mess);
|
||||
|
||||
// unrecognized function, do not ask for retval
|
||||
if(strstr(mess,"Unrecognized Function") != nullptr)
|
||||
unrecognizedFunction = true;
|
||||
// delete allocated mess
|
||||
if (created)
|
||||
delete [] mess;
|
||||
}
|
||||
// get retval
|
||||
if (!unrecognizedFunction)
|
||||
mySocket->ReceiveDataOnly(retval, sizeOfRetval);
|
||||
}
|
||||
|
||||
|
||||
int ServerInterface::Client_Send(int fnum,
|
||||
void* args, int sizeOfArgs,
|
||||
void* retval, int sizeOfRetval,
|
||||
char* mess) {
|
||||
int ret = FAIL;
|
||||
mySocket->SendDataOnly(&fnum,sizeof(fnum));
|
||||
mySocket->SendDataOnly(args, sizeOfArgs);
|
||||
Client_Receive(ret, mess, retval, sizeOfRetval);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int ServerInterface::Server_SendResult(bool update, int ret,
|
||||
void* retval, int retvalSize, char* mess) {
|
||||
|
||||
// update if different clients
|
||||
if (update && ret == OK && mySocket->differentClients)
|
||||
ret = FORCE_UPDATE;
|
||||
|
||||
// send success of operation
|
||||
mySocket->SendDataOnly(&ret,sizeof(ret));
|
||||
if(ret == FAIL) {
|
||||
// send error message
|
||||
if (mess)
|
||||
mySocket->SendDataOnly(mess, MAX_STR_LENGTH);
|
||||
// debugging feature. should not happen.
|
||||
else
|
||||
FILE_LOG(logERROR) << "No error message provided for this failure. Will mess up TCP\n";
|
||||
}
|
||||
// send return value
|
||||
mySocket->SendDataOnly(retval, retvalSize);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int ServerInterface::Server_ReceiveArg(int& ret, char* mess, void* arg, int sizeofArg, bool checkbase, void* base) {
|
||||
// client socket crash, cannot receive arguments
|
||||
if (sizeofArg && mySocket->ReceiveDataOnly(arg, sizeofArg) < 0)
|
||||
return Server_SocketCrash();
|
||||
|
||||
// check if server object created
|
||||
if (checkbase && base == nullptr)
|
||||
Server_NullObjectError(ret, mess);
|
||||
|
||||
// no crash
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
int ServerInterface::Server_VerifyLock(int& ret, char* mess, int lockstatus) {
|
||||
// server locked
|
||||
if (mySocket->differentClients && lockstatus)
|
||||
return Server_LockedError(ret, mess);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int ServerInterface::Server_VerifyLockAndIdle(int& ret, char* mess, int lockstatus, slsDetectorDefs::runStatus status, int fnum) {
|
||||
// server locked
|
||||
if (mySocket->differentClients && lockstatus)
|
||||
return Server_LockedError(ret, mess);
|
||||
|
||||
// server not idle for this command
|
||||
if (status != slsDetectorDefs::IDLE)
|
||||
return Server_NotIdleError(ret, mess, fnum);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void ServerInterface::Server_NullObjectError(int& ret, char* mess) {
|
||||
ret=FAIL;
|
||||
strcpy(mess,"Receiver not set up. Please use rx_hostname first.\n");
|
||||
FILE_LOG(logERROR) << mess;
|
||||
}
|
||||
|
||||
|
||||
int ServerInterface::Server_SocketCrash() {
|
||||
FILE_LOG(logERROR) << "Reading from socket failed. Possible socket crash";
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
|
||||
int ServerInterface::Server_LockedError(int& ret, char* mess) {
|
||||
ret = FAIL;
|
||||
sprintf(mess,"Receiver locked by %s\n", mySocket->lastClientIP);
|
||||
FILE_LOG(logERROR) << mess;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int ServerInterface::Server_NotIdleError(int& ret, char* mess, int fnum) {
|
||||
ret = FAIL;
|
||||
sprintf(mess,"Can not execute %s when receiver is not idle\n",
|
||||
getFunctionNameFromEnum((enum detFuncs)fnum));
|
||||
FILE_LOG(logERROR) << mess;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
79
slsSupportLib/src/ServerSocket.cpp
Executable file
79
slsSupportLib/src/ServerSocket.cpp
Executable file
@ -0,0 +1,79 @@
|
||||
#include "ServerSocket.h"
|
||||
#include "DataSocket.h"
|
||||
#include "logger.h"
|
||||
#include "sls_detector_defs.h"
|
||||
#include "sls_detector_exceptions.h"
|
||||
#include "string_utils.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#define DEFAULT_PACKET_SIZE 1286
|
||||
#define SOCKET_BUFFER_SIZE (100 * 1024 * 1024) // 100 MB
|
||||
#define DEFAULT_BACKLOG 5
|
||||
|
||||
namespace sls {
|
||||
|
||||
ServerSocket::ServerSocket(int port)
|
||||
: DataSocket(socket(AF_INET, SOCK_STREAM, 0)), serverPort(port) {
|
||||
|
||||
struct sockaddr_in serverAddr;
|
||||
serverAddr.sin_family = AF_INET;
|
||||
serverAddr.sin_port = htons(port);
|
||||
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
|
||||
if (bind(getSocketId(), (struct sockaddr *)&serverAddr,
|
||||
sizeof(serverAddr)) != 0) {
|
||||
close();
|
||||
throw std::runtime_error("Server ERROR: cannot bind socket");
|
||||
}
|
||||
if (listen(getSocketId(), DEFAULT_BACKLOG) != 0) {
|
||||
close();
|
||||
throw std::runtime_error("Server ERROR: cannot listen to socket");
|
||||
}
|
||||
}
|
||||
|
||||
DataSocket ServerSocket::accept() {
|
||||
struct sockaddr_in clientAddr;
|
||||
socklen_t addr_size = sizeof clientAddr;
|
||||
int newSocket =
|
||||
::accept(getSocketId(), (struct sockaddr *)&clientAddr, &addr_size);
|
||||
if (newSocket == -1) {
|
||||
throw std::runtime_error("Server ERROR: socket accept failed\n");
|
||||
}
|
||||
inet_ntop(AF_INET, &(clientAddr.sin_addr), &thisClient_.front(),
|
||||
INET_ADDRSTRLEN);
|
||||
std::cout << "lastClient: " << lastClient_ << " thisClient: " << thisClient_
|
||||
<< '\n';
|
||||
// Here goes any check for locks etc
|
||||
lastClient_ = thisClient_;
|
||||
|
||||
return DataSocket(newSocket);
|
||||
}
|
||||
|
||||
const std::string &ServerSocket::getLastClient() { return lastClient_; }
|
||||
|
||||
int ServerSocket::getPort() const { return serverPort; }
|
||||
|
||||
void ServerSocket::SendResult(int &ret, void* retval, int retvalSize, char* mess) {
|
||||
|
||||
// send success of operation
|
||||
sendData(&ret, sizeof(ret));
|
||||
|
||||
if (ret == slsDetectorDefs::FAIL) {
|
||||
// create error message if empty
|
||||
if (!strlen(mess)) {
|
||||
strcpy(mess, "No error message provided for this failure in server. Will mess up TCP.");
|
||||
}
|
||||
|
||||
sendData(mess, MAX_STR_LENGTH);
|
||||
throw sls::RuntimeError(mess);
|
||||
}
|
||||
// send return value
|
||||
sendData(retval, retvalSize);
|
||||
}
|
||||
|
||||
|
||||
}; // namespace sls
|
81
slsSupportLib/src/file_utils.cpp
Executable file
81
slsSupportLib/src/file_utils.cpp
Executable file
@ -0,0 +1,81 @@
|
||||
#include "file_utils.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
int readDataFile(std::ifstream &infile, short int *data, int nch, int offset) {
|
||||
int ichan, iline=0;
|
||||
short int idata;
|
||||
int interrupt=0;
|
||||
std::string str;
|
||||
while (infile.good() and interrupt==0) {
|
||||
getline(infile,str);
|
||||
std::istringstream ssstr(str);
|
||||
ssstr >> ichan >> idata;
|
||||
if (ssstr.fail() || ssstr.bad()) {
|
||||
interrupt=1;
|
||||
break;
|
||||
}
|
||||
if (iline<nch) {
|
||||
if (ichan>=offset) {
|
||||
data[iline]=idata;
|
||||
iline++;
|
||||
}
|
||||
} else {
|
||||
interrupt=1;
|
||||
break;
|
||||
}
|
||||
return iline;
|
||||
};
|
||||
return iline;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int readDataFile(std::string fname, short int *data, int nch) {
|
||||
std::ifstream infile;
|
||||
int iline=0;
|
||||
std::string str;
|
||||
infile.open(fname.c_str(), std::ios_base::in);
|
||||
if (infile.is_open()) {
|
||||
iline=readDataFile(infile, data, nch, 0);
|
||||
infile.close();
|
||||
} else {
|
||||
FILE_LOG(logERROR) << "Could not read file " << fname;
|
||||
return -1;
|
||||
}
|
||||
return iline;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int writeDataFile(std::ofstream &outfile,int nch, short int *data, int offset) {
|
||||
if (data==nullptr)
|
||||
return slsDetectorDefs::FAIL;
|
||||
for (int ichan=0; ichan<nch; ichan++)
|
||||
outfile << ichan+offset << " " << *(data+ichan) << std::endl;
|
||||
return slsDetectorDefs::OK;
|
||||
}
|
||||
|
||||
|
||||
int writeDataFile(std::string fname,int nch, short int *data) {
|
||||
std::ofstream outfile;
|
||||
if (data==nullptr)
|
||||
return slsDetectorDefs::FAIL;
|
||||
outfile.open (fname.c_str(),std::ios_base::out);
|
||||
if (outfile.is_open()) {
|
||||
writeDataFile(outfile, nch, data, 0);
|
||||
outfile.close();
|
||||
return slsDetectorDefs::OK;
|
||||
} else {
|
||||
FILE_LOG(logERROR) << "Could not open file " << fname << "for writing";
|
||||
return slsDetectorDefs::FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
95
slsSupportLib/src/network_utils.cpp
Executable file
95
slsSupportLib/src/network_utils.cpp
Executable file
@ -0,0 +1,95 @@
|
||||
#include "sls_detector_exceptions.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "network_utils.h"
|
||||
|
||||
namespace sls {
|
||||
|
||||
IpAddr::IpAddr(const std::string &address) {
|
||||
inet_pton(AF_INET, address.c_str(), &addr_);
|
||||
}
|
||||
|
||||
IpAddr::IpAddr(const char *address) {
|
||||
inet_pton(AF_INET, address, &addr_);
|
||||
}
|
||||
|
||||
std::string IpAddr::str() const {
|
||||
char ipstring[INET_ADDRSTRLEN]{};
|
||||
inet_ntop(AF_INET, &addr_, ipstring, INET_ADDRSTRLEN);
|
||||
return ipstring;
|
||||
}
|
||||
std::string IpAddr::hex() const {
|
||||
std::ostringstream ss;
|
||||
ss << std::hex << std::setfill('0') << std::setw(2);
|
||||
for (int i = 0; i != 4; ++i) {
|
||||
ss << ((addr_ >> i * 8) & 0xFF);
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
MacAddr::MacAddr(std::string mac) {
|
||||
if ((mac.length() != 17) || (mac[2] != ':') || (mac[5] != ':') ||
|
||||
(mac[8] != ':') || (mac[11] != ':') || (mac[14] != ':')) {
|
||||
addr_ = 0;
|
||||
} else {
|
||||
mac.erase(std::remove(mac.begin(), mac.end(), ':'), mac.end());
|
||||
addr_ = std::strtoul(mac.c_str(), nullptr, 16);
|
||||
}
|
||||
}
|
||||
MacAddr::MacAddr(const char *address) : MacAddr(std::string(address)) {}
|
||||
|
||||
std::string MacAddr::to_hex(const char delimiter) const {
|
||||
std::ostringstream ss;
|
||||
ss << std::hex << std::setfill('0') << std::setw(2);
|
||||
ss << ((addr_ >> 40) & 0xFF);
|
||||
for (int i = 32; i >= 0; i -= 8) {
|
||||
if (delimiter)
|
||||
ss << delimiter;
|
||||
ss << ((addr_ >> i) & 0xFF);
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string MacAddr::str() const {
|
||||
return to_hex(':');
|
||||
}
|
||||
|
||||
std::string MacAddr::hex() const {
|
||||
return to_hex();
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const IpAddr &addr) {
|
||||
return out << addr.str();
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const MacAddr &addr) {
|
||||
return out << addr.str();
|
||||
}
|
||||
|
||||
uint32_t HostnameToIp(const char *hostname) {
|
||||
addrinfo hints;
|
||||
addrinfo *result = nullptr;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
if (getaddrinfo(hostname, NULL, &hints, &result)) {
|
||||
freeaddrinfo(result);
|
||||
throw RuntimeError("Could not convert hostname to ip");
|
||||
}
|
||||
uint32_t ip = ((sockaddr_in *)result->ai_addr)->sin_addr.s_addr;
|
||||
freeaddrinfo(result);
|
||||
return ip;
|
||||
}
|
||||
|
||||
} // namespace sls
|
54
slsSupportLib/src/string_utils.cpp
Executable file
54
slsSupportLib/src/string_utils.cpp
Executable file
@ -0,0 +1,54 @@
|
||||
|
||||
#include "string_utils.h"
|
||||
#include "container_utils.h"
|
||||
#include "network_utils.h"
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
namespace sls {
|
||||
|
||||
std::vector<std::string> split(const std::string &strToSplit, char delimeter) {
|
||||
std::stringstream ss(strToSplit);
|
||||
std::string item;
|
||||
std::vector<std::string> splittedStrings;
|
||||
while (std::getline(ss, item, delimeter)) {
|
||||
splittedStrings.push_back(item);
|
||||
}
|
||||
return splittedStrings;
|
||||
}
|
||||
|
||||
std::string concatenateNonEmptyStrings(const std::vector<std::string> &vec) {
|
||||
std::string ret;
|
||||
for (const auto &s : vec)
|
||||
if (!s.empty())
|
||||
ret += s + '+';
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string concatenateIfDifferent(const std::vector<std::string> &container) {
|
||||
if (allEqual(container)) {
|
||||
return container.front();
|
||||
} else {
|
||||
std::string result;
|
||||
for (const auto &s : container)
|
||||
result += s + '+';
|
||||
return result;
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
std::string concatenateIfDifferent(const std::vector<T> &container) {
|
||||
if (allEqual(container)) {
|
||||
return container.front().str();
|
||||
} else {
|
||||
std::string result;
|
||||
for (const auto &s : container)
|
||||
result += s.str() + '+';
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template std::string concatenateIfDifferent(const std::vector<IpAddr> &);
|
||||
template std::string concatenateIfDifferent(const std::vector<MacAddr> &);
|
||||
|
||||
}; // namespace sls
|
Reference in New Issue
Block a user