mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2026-01-19 08:48:51 +01:00
new socket for slsDetector
This commit is contained in:
@@ -21,13 +21,16 @@ public:
|
||||
* @param n for debugging purposes (useful only for client side)
|
||||
* @param t string to identify type (Detector, Receiver) for printouts (useful only for client side)
|
||||
*/
|
||||
ClientInterface(int n, sls::ClientSocket&& s);
|
||||
ClientInterface(sls::ClientSocket* socket, int n);
|
||||
|
||||
/**
|
||||
* destructor
|
||||
*/
|
||||
virtual ~ClientInterface() = default;
|
||||
|
||||
void SetSocket(sls::ClientSocket *socket){
|
||||
socket_ = socket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive ret, mess or retval from Server
|
||||
@@ -61,7 +64,7 @@ private:
|
||||
/**
|
||||
* socket for data acquisition
|
||||
*/
|
||||
sls::ClientSocket socket_;
|
||||
sls::ClientSocket* socket_;
|
||||
|
||||
/** index for client debugging purposes */
|
||||
int index;
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
#pragma once
|
||||
#include "DataSocket.h"
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <netdb.h>
|
||||
#include <string>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
namespace sls{
|
||||
namespace sls {
|
||||
|
||||
class ClientSocket: public DataSocket{
|
||||
public:
|
||||
ClientSocket(const std::string& hostname, uint16_t port_number);
|
||||
int connect();
|
||||
private:
|
||||
class ClientSocket : public DataSocket {
|
||||
public:
|
||||
ClientSocket(const std::string &hostname, uint16_t port_number);
|
||||
int sendCommandThenRead(int fnum, void *args, size_t args_size, void *retval, size_t retval_size);
|
||||
|
||||
private:
|
||||
void readReply(int &ret, void *retval, size_t retval_size);
|
||||
struct sockaddr_in serverAddr {};
|
||||
};
|
||||
|
||||
|
||||
@@ -1,27 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <netdb.h>
|
||||
namespace sls {
|
||||
|
||||
class DataSocket {
|
||||
public:
|
||||
DataSocket(int socketId);
|
||||
DataSocket(DataSocket&& move) noexcept;
|
||||
DataSocket& operator=(DataSocket&& move) noexcept;
|
||||
void swap(DataSocket& other) noexcept;
|
||||
DataSocket(DataSocket const&) = delete;
|
||||
DataSocket& operator=(DataSocket const&) = delete;
|
||||
int getSocketId() const{
|
||||
DataSocket(DataSocket &&move) noexcept;
|
||||
virtual ~DataSocket();
|
||||
DataSocket &operator=(DataSocket &&move) noexcept;
|
||||
void swap(DataSocket &other) noexcept;
|
||||
DataSocket(DataSocket const &) = delete;
|
||||
DataSocket &operator=(DataSocket const &) = delete;
|
||||
int getSocketId() const {
|
||||
return socketId_;
|
||||
}
|
||||
size_t sendData(char *buffer, size_t size);
|
||||
size_t receiveData(char * buffer, size_t size);
|
||||
|
||||
size_t sendData(void *buffer, size_t size);
|
||||
size_t receiveData(void *buffer, size_t size);
|
||||
int setTimeOut(int t_seconds);
|
||||
void close();
|
||||
|
||||
private:
|
||||
int socketId_ = -1;
|
||||
};
|
||||
|
||||
int ConvertHostnameToInternetAddress(const char *const hostname, struct ::addrinfo **res);
|
||||
int ConvertInternetAddresstoIpString(struct ::addrinfo *res, char *ip, const int ipsize);
|
||||
|
||||
}; // namespace sls
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef FILELOG_MAX_LEVEL
|
||||
#define FILELOG_MAX_LEVEL logINFO
|
||||
#define FILELOG_MAX_LEVEL logDEBUG5
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#include "ClientInterface.h"
|
||||
#include "ClientSocket.h"
|
||||
|
||||
ClientInterface::ClientInterface(int n, sls::ClientSocket&& s): socket_(std::move(s)),
|
||||
ClientInterface::ClientInterface(sls::ClientSocket* socket, int n): socket_(socket),
|
||||
index(n){}
|
||||
|
||||
void ClientInterface::Client_Receive(int& ret, char* mess, void* retval, int sizeOfRetval) {
|
||||
// get result of operation
|
||||
socket_.receiveData(reinterpret_cast<char *>(&ret), sizeof(ret));
|
||||
socket_->receiveData(reinterpret_cast<char *>(&ret), sizeof(ret));
|
||||
|
||||
bool unrecognizedFunction = false;
|
||||
if (ret == FAIL) {
|
||||
@@ -18,7 +18,7 @@ void ClientInterface::Client_Receive(int& ret, char* mess, void* retval, int siz
|
||||
memset(mess, 0, MAX_STR_LENGTH);
|
||||
}
|
||||
// get error message
|
||||
socket_.receiveData(mess,MAX_STR_LENGTH);
|
||||
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
|
||||
@@ -30,7 +30,7 @@ void ClientInterface::Client_Receive(int& ret, char* mess, void* retval, int siz
|
||||
}
|
||||
// get retval
|
||||
if (!unrecognizedFunction)
|
||||
socket_.receiveData( reinterpret_cast<char *>(retval), sizeOfRetval);
|
||||
socket_->receiveData( reinterpret_cast<char *>(retval), sizeOfRetval);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,8 +39,8 @@ int ClientInterface::Client_Send(int fnum,
|
||||
void* retval, int sizeOfRetval,
|
||||
char* mess) {
|
||||
int ret = FAIL;
|
||||
socket_.sendData(reinterpret_cast<char *>(&fnum),sizeof(fnum));
|
||||
socket_.sendData(reinterpret_cast<char *>(args), sizeOfArgs);
|
||||
socket_->sendData(reinterpret_cast<char *>(&fnum),sizeof(fnum));
|
||||
socket_->sendData(reinterpret_cast<char *>(args), sizeOfArgs);
|
||||
Client_Receive(ret, mess, retval, sizeOfRetval);
|
||||
return ret;
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
#include "ClientSocket.h"
|
||||
#include <arpa/inet.h>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sls_detector_defs.h"
|
||||
namespace sls {
|
||||
|
||||
ClientSocket::ClientSocket(const std::string &host, uint16_t port) : DataSocket(socket(AF_INET, SOCK_STREAM, 0)) {
|
||||
@@ -13,7 +14,7 @@ ClientSocket::ClientSocket(const std::string &host, uint16_t port) : DataSocket(
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_flags |= AI_CANONNAME;
|
||||
|
||||
|
||||
if (getaddrinfo(host.c_str(), NULL, &hints, &result) != 0) {
|
||||
throw std::runtime_error("ClientSocket ERROR: cannot decode host\n");
|
||||
}
|
||||
@@ -23,18 +24,40 @@ ClientSocket::ClientSocket(const std::string &host, uint16_t port) : DataSocket(
|
||||
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));
|
||||
&((struct sockaddr_in *)result->ai_addr)->sin_addr, sizeof(in_addr_t));
|
||||
|
||||
if (::connect(getSocketId(), (struct sockaddr *)&serverAddr, sizeof(serverAddr)) != 0){
|
||||
if (::connect(getSocketId(), (struct sockaddr *)&serverAddr, sizeof(serverAddr)) != 0) {
|
||||
freeaddrinfo(result);
|
||||
throw std::runtime_error("ClientSocket ERROR: cannot connect to host\n");
|
||||
}
|
||||
freeaddrinfo(result);
|
||||
}
|
||||
|
||||
int ClientSocket::connect(){
|
||||
//used to reconnect after closing may be removed
|
||||
return ::connect(getSocketId(), (struct sockaddr *)&serverAddr, sizeof(serverAddr));
|
||||
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));
|
||||
bool unrecognizedFunction = false;
|
||||
if (ret == slsDetectorDefs::FAIL) {
|
||||
char mess[MAX_STR_LENGTH]{};
|
||||
//get error message
|
||||
receiveData(mess, sizeof(mess));
|
||||
// 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;
|
||||
}
|
||||
// get retval
|
||||
if (!unrecognizedFunction)
|
||||
receiveData(retval, retval_size);
|
||||
}
|
||||
|
||||
}; //namespace sls
|
||||
@@ -73,7 +73,10 @@ void CmdLineParser::DecodeIdAndPosition(const char *c) {
|
||||
|
||||
std::vector<char *> CmdLineParser::argv() {
|
||||
std::vector<char *> vec;
|
||||
vec.push_back(&command_.front());
|
||||
if (command_.empty()!=true){
|
||||
vec.push_back(&command_.front());
|
||||
}
|
||||
|
||||
for (auto &arg : arguments_) {
|
||||
vec.push_back(&arg.front());
|
||||
}
|
||||
|
||||
@@ -1,44 +1,83 @@
|
||||
|
||||
#include "DataSocket.h"
|
||||
#include "logger.h"
|
||||
#include <algorithm>
|
||||
#include <arpa/inet.h>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <netdb.h>
|
||||
|
||||
namespace sls {
|
||||
|
||||
DataSocket::DataSocket(int socketId) : socketId_(socketId) {}
|
||||
|
||||
void DataSocket::swap(DataSocket& other) noexcept{
|
||||
DataSocket::~DataSocket() {
|
||||
if (socketId_ == -1) {
|
||||
return;
|
||||
} else {
|
||||
try {
|
||||
close();
|
||||
} catch (...) {
|
||||
//pass
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DataSocket::swap(DataSocket &other) noexcept {
|
||||
std::swap(socketId_, other.socketId_);
|
||||
}
|
||||
|
||||
DataSocket::DataSocket(DataSocket&& move) noexcept{
|
||||
DataSocket::DataSocket(DataSocket &&move) noexcept {
|
||||
move.swap(*this);
|
||||
}
|
||||
DataSocket& DataSocket::operator=(DataSocket&& move)noexcept{
|
||||
DataSocket &DataSocket::operator=(DataSocket &&move) noexcept {
|
||||
move.swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_t DataSocket::receiveData(char *buffer, size_t size) {
|
||||
std::cout << "Sending\n";
|
||||
size_t DataSocket::receiveData(void *buffer, size_t size) {
|
||||
// std::cout << "Sending\n";
|
||||
size_t dataRead = 0;
|
||||
while (dataRead < size) {
|
||||
dataRead += read(getSocketId(), buffer + dataRead, size - dataRead);
|
||||
dataRead += read(getSocketId(), reinterpret_cast<char *>(buffer) + dataRead, size - dataRead);
|
||||
}
|
||||
return dataRead;
|
||||
}
|
||||
|
||||
size_t DataSocket::sendData(char *buffer, size_t size) {
|
||||
std::cout << "Receiving\n";
|
||||
size_t DataSocket::sendData(void *buffer, size_t size) {
|
||||
// std::cout << "Receiving\n";
|
||||
size_t dataSent = 0;
|
||||
while (dataSent < size) {
|
||||
dataSent += write(getSocketId(), buffer + dataSent, size - dataSent);
|
||||
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) {
|
||||
::close(socketId_);
|
||||
@@ -47,4 +86,45 @@ void DataSocket::close() {
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -250,4 +250,17 @@ TEST_CASE("Parses string with two arguments") {
|
||||
REQUIRE("3000" == p.arguments()[0]);
|
||||
REQUIRE("4000" == p.arguments()[1]);
|
||||
REQUIRE(p.arguments().size() == 2);
|
||||
}
|
||||
|
||||
TEST_CASE("Build up argv"){
|
||||
CmdLineParser p;
|
||||
// p.argv();
|
||||
REQUIRE(p.argv().empty());
|
||||
REQUIRE(p.argv().data() == nullptr);
|
||||
|
||||
std::string s = "trimen 3000 4000\n";
|
||||
p.Parse(s);
|
||||
REQUIRE(p.argv().data() != nullptr);
|
||||
REQUIRE(p.argv().size() == 3);
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user