starting to add new Socket interface

This commit is contained in:
Erik Frojdh 2019-01-23 11:47:13 +01:00
parent 3eca4c0535
commit 99a1c609f1
10 changed files with 212 additions and 21 deletions

View File

@ -1,5 +1,6 @@
#include "slsDetector.h"
#include "ClientInterface.h"
#include "ClientSocket.h"
#include "MySocketTCP.h"
#include "SharedMemory.h"
#include "file_utils.h"
@ -736,30 +737,17 @@ slsDetectorDefs::detectorType slsDetector::getDetectorTypeAsEnum(const std::stri
int fnum = F_GET_DETECTOR_TYPE;
int ret = FAIL;
detectorType retval = GENERIC;
MySocketTCP *mySocket = nullptr;
try {
mySocket = new MySocketTCP(hostname.c_str(), cport);
} catch (...) {
FILE_LOG(logERROR) << "Cannot create socket to control server " << hostname
<< " over port " << cport;
return retval;
}
FILE_LOG(logDEBUG1) << "Getting detector type ";
if (mySocket->Connect() >= 0) {
mySocket->SendDataOnly(&fnum, sizeof(fnum));
mySocket->ReceiveDataOnly(&ret, sizeof(ret));
mySocket->ReceiveDataOnly(&retval, sizeof(retval));
mySocket->Disconnect();
} else {
try{
sls::ClientSocket cs(hostname, cport);
cs.sendData(reinterpret_cast<char *>(&fnum), sizeof(fnum));
cs.receiveData(reinterpret_cast<char *>(&ret), sizeof(ret));
cs.receiveData(reinterpret_cast<char *>(&retval), sizeof(retval));
}catch(...){
//TODO! (Erik) Do not swallow exception but let the caller handle it
FILE_LOG(logERROR) << "Cannot connect to server " << hostname << " over port " << cport;
}
if (ret != FAIL) {
FILE_LOG(logDEBUG1) << "Detector type is " << retval;
}
delete mySocket;
FILE_LOG(logDEBUG1) << "Detector type is " << retval;
return retval;
}

View File

@ -3,6 +3,9 @@ set(SOURCES
src/CmdLineParser.cpp
src/string_utils.cpp
src/file_utils.cpp
src/ClientSocket.cpp
src/DataSocket.cpp
src/ServerSocket.cpp
)
set(HEADERS
@ -22,6 +25,9 @@ set(PUBLICHEADERS
include/MySocketTCP.h
include/genericSocket.h
include/logger.h
include/ClientSocket.h
include/DataSocket.h
include/ServerSocket.h
)
add_library(slsSupportLib SHARED

View File

@ -0,0 +1,17 @@
#pragma once
#include "DataSocket.h"
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <string>
namespace sls{
class ClientSocket: public DataSocket{
public:
ClientSocket(const std::string& hostname, uint16_t port_number);
private:
};
}; //namespace sls

View File

@ -0,0 +1,23 @@
#pragma once
#include <cstdint>
#include <cstddef>
namespace sls {
class DataSocket {
public:
DataSocket(int socketId);
int getSocketId() const{
return socketId_;
}
size_t sendData(char *buffer, size_t size);
size_t receiveData(char * buffer, size_t size);
void close();
private:
int socketId_ = -1;
};
}; // namespace sls

View File

@ -0,0 +1,25 @@
#pragma once
#include "DataSocket.h"
#include <cstdint>
#include <netdb.h>
#include <string>
#include <sys/socket.h>
#include <sys/types.h>
namespace sls {
class ServerSocket : public DataSocket {
public:
ServerSocket(int port);
DataSocket accept();
const std::string &getLastClient() { return lastClient_; }
private:
std::string lastClient_ = std::string(INET_ADDRSTRLEN, '\0');
std::string thisClient_ = std::string(INET_ADDRSTRLEN, '\0');
// char lastClient_[INET_ADDRSTRLEN]{};
};
}; //namespace sls

View File

@ -0,0 +1,35 @@
#include "ClientSocket.h"
#include <arpa/inet.h>
#include <cstring>
#include <iostream>
#include <unistd.h>
namespace sls {
ClientSocket::ClientSocket(const std::string &host, uint16_t port) : DataSocket(socket(AF_INET, SOCK_STREAM, 0)) {
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) {
throw std::runtime_error("ClientSocket ERROR: cannot decode host\n");
}
//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);
throw std::runtime_error("ClientSocket ERROR: cannot connect to host\n");
}
freeaddrinfo(result);
}
}; //namespace sls

View File

@ -0,0 +1,38 @@
#include "DataSocket.h"
#include <arpa/inet.h>
#include <cstring>
#include <iostream>
#include <unistd.h>
namespace sls {
DataSocket::DataSocket(int socketId) : socketId_(socketId) {}
size_t DataSocket::receiveData(char *buffer, size_t size) {
std::cout << "Sending\n";
size_t dataRead = 0;
while (dataRead < size) {
dataRead += read(getSocketId(), buffer + dataRead, size - dataRead);
}
return dataRead;
}
size_t DataSocket::sendData(char *buffer, size_t size) {
std::cout << "Receiving\n";
size_t dataSent = 0;
while (dataSent < size) {
dataSent += write(getSocketId(), buffer + dataSent, size - dataSent);
}
return dataSent;
}
void DataSocket::close() {
if (socketId_ > 0) {
::close(socketId_);
} else {
throw std::runtime_error("Socket ERROR: close called on bad socket\n");
}
}
} // namespace sls

View File

@ -0,0 +1,46 @@
#include "ServerSocket.h"
#include "DataSocket.h"
#include <arpa/inet.h>
#include <iostream>
#include <unistd.h>
#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)) {
std::cout << "Server constructed\n";
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);
}
}; //namespace sls

View File

@ -7,6 +7,7 @@ include_directories(
set(SOURCES
test.cpp
test-ClientInterface.cpp
test-CmdLineParser.cpp
test-container_utils.cpp
test-string_utils.cpp

View File

@ -0,0 +1,12 @@
#include "ClientInterface.h"
#include "MySocketTCP.h"
#include "catch.hpp"
//tests to add
//help for all docs
//command for all depreciated commands
TEST_CASE("hopp") {
REQUIRE(true);
}