1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
|
// Copyright (c) 2015-2020 Josh Blum
// SPDX-License-Identifier: BSL-1.0
#pragma once
#include "SoapyRemoteConfig.hpp"
#include <cstddef>
#include <string>
#include <vector>
class SockAddrData;
/*!
* Create one instance of the session per process to use sockets.
*/
class SOAPY_REMOTE_API SoapySocketSession
{
public:
SoapySocketSession(void);
~SoapySocketSession(void);
};
/*!
* A simple socket wrapper with a TCP-like socket API.
* The implementation may be swapped out in the future.
*/
class SOAPY_REMOTE_API SoapyRPCSocket
{
public:
SoapyRPCSocket(void);
/*!
* Make the underlying socket (but does not bind or connect).
* This function is called automatically by bind and connect,
* however it can be used to test if a protocol is possible.
*/
SoapyRPCSocket(const std::string &url);
~SoapyRPCSocket(void);
/*!
* Is the socket null?
* The default constructor makes a null socket.
* The socket is non null after bind or connect,
* and after accept returns a successful socket.
*/
bool null(void);
/*!
* Is the socket in a good state?
* Return true for good, false for error.
* The last error message will be set on error.
*/
bool status(void);
/*!
* Explicit close the socket, also done by destructor.
*/
int close(void);
/*!
* Server bind.
* URL examples:
* 0.0.0.0:1234
* [::]:1234
*/
int bind(const std::string &url);
/*!
* Server listen.
*/
int listen(int backlog);
/*!
* Server accept connection.
* Socket will be null on failure.
* Caller owns the client socket.
*/
SoapyRPCSocket *accept(void);
/*!
* Client connect.
* URL examples:
* 10.10.1.123:1234
* [2001:db8:0:1]:1234
* hostname:1234
*/
int connect(const std::string &url);
/*!
* Connect to client with a timeout is microseconds.
*/
int connect(const std::string &url, const long timeoutUs);
//! set or clear non blocking on socket
int setNonBlocking(const bool nonblock);
/*!
* Join a multi-cast group.
* \param group the url for the multicast group and port number
* \param sendAddr the url for the multicast send interface
* \param recvAddrs a list of interfaces for multicast membership
* \param loop specify to receive local loopback
* \param ttl specify time to live for send packets
* \param iface the IPv6 interface index or 0 for automatic
*/
int multicastJoin(const std::string &group, const std::string &sendAddr, const std::vector<std::string> &recvAddrs, const bool loop = true, const int ttl = 1);
/*!
* Send the buffer and return bytes sent or error.
*/
int send(const void *buf, size_t len, int flags = 0);
/*!
* Receive into buffer and return bytes received or error.
*/
int recv(void *buf, size_t len, int flags = 0);
/*!
* Send to a specific destination.
*/
int sendto(const void *buf, size_t len, const std::string &url, int flags = 0);
/*!
* Receive from an unconnected socket.
*/
int recvfrom(void *buf, size_t len, std::string &url, int flags = 0);
/*!
* Wait for recv to become ready with timeout.
* Return true for ready, false for timeout.
*/
bool selectRecv(const long timeoutUs);
/*!
* Wait for recv ready on multiple sockets.
* Set the output ready vector to true for ready or false
* Return a count of sockets that are ready or -1 for error
*/
static int selectRecvMultiple(const std::vector<SoapyRPCSocket *> &socks, std::vector<bool> &ready, const long timeoutUs);
/*!
* Query the last error message as a string.
*/
const char *lastErrorMsg(void) const
{
return _lastErrorMsg.c_str();
}
/*!
* Get the URL of the local socket.
* Return an empty string on error.
*/
std::string getsockname(void);
/*!
* Get the URL of the remote socket.
* Return an empty string on error.
*/
std::string getpeername(void);
/*!
* Set the socket buffer size in bytes.
* \param isRecv true for RCVBUF, false for SNDBUF
* \return 0 for success or negative error code.
*/
int setBuffSize(const bool isRecv, const size_t numBytes);
/*!
* Get the socket buffer size in bytes.
* \param isRecv true for RCVBUF, false for SNDBUF
* \return the actual size set or negative error code.
*/
int getBuffSize(const bool isRecv);
private:
int _sock;
std::string _lastErrorMsg;
void reportError(const std::string &what, const std::string &errorMsg);
void reportError(const std::string &what, const int err);
void reportError(const std::string &what);
void setDefaultTcpSockOpts(void);
};
|