Socket.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. /*
  2. * Author: Patrick-Christopher Mattulat
  3. * Company: Lynar Studios
  4. * E-Mail: webmaster@lynarstudios.com
  5. * Created: 2022-11-16
  6. * Changed: 2022-12-28
  7. *
  8. * */
  9. #include <ls_std/os/specification.hpp>
  10. #include <ls_std/network/socket/Socket.hpp>
  11. #include <ls_std/network/core/ProtocolFamilyMapper.hpp>
  12. #include <ls_std/network/core/ProtocolMapper.hpp>
  13. #include <ls_std/network/socket/ConvertedSocketAddress.hpp>
  14. #include <ls_std/network/socket/SocketAddressMapper.hpp>
  15. #include <ls_std/common/api/socket/PosixSocket.hpp>
  16. #include <ls_std/common/api/io/PosixReader.hpp>
  17. #include <ls_std/common/api/io/PosixWriter.hpp>
  18. #include <ls_std/core/exception/WrongProtocolException.hpp>
  19. #include <ls_std/core/exception/IllegalArgumentException.hpp>
  20. #include <ls_std/core/exception/FileOperationException.hpp>
  21. #include <memory>
  22. #include <ls_std/core/exception/SocketOperationFailedException.hpp>
  23. #include <iostream>
  24. ls::std::network::Socket::Socket(ls::std::network::SocketParameter _parameter) : ls::std::core::Class("Socket"),
  25. parameter(::std::move(_parameter))
  26. {
  27. this->_init();
  28. }
  29. ls::std::network::Socket::~Socket()
  30. {
  31. delete[] this->readBuffer;
  32. #if LS_STD_UNIX_PLATFORM
  33. for (const auto& connection : this->unixDescriptors)
  34. {
  35. if (!this->_closeUnix(connection.second))
  36. {
  37. ::std::cerr << "could not close socket with id \"" << connection.first << "\"" << ::std::endl;
  38. }
  39. }
  40. #endif
  41. }
  42. ls::std::core::type::byte_field ls::std::network::Socket::read()
  43. {
  44. if (!this->readBufferSet)
  45. {
  46. this->_initReadBuffer(); // TODO: is this really wise to initialize once? what if reading second time wouldn't work? - test it with unit tests and remove it
  47. this->readBufferSet = true;
  48. }
  49. return this->_read();
  50. }
  51. bool ls::std::network::Socket::write(const ls::std::core::type::byte_field &_data)
  52. {
  53. return this->_write(_data);
  54. }
  55. ls::std::core::type::connection_id ls::std::network::Socket::accept()
  56. {
  57. if (this->parameter.socketAddress.protocolType != LS_STD_PROTOCOL_TYPE_TCP)
  58. {
  59. throw ls::std::core::WrongProtocolException{};
  60. }
  61. #if LS_STD_UNIX_PLATFORM
  62. return ls::std::network::Socket::_acceptUnix();
  63. #endif
  64. }
  65. bool ls::std::network::Socket::bind()
  66. {
  67. #if LS_STD_UNIX_PLATFORM
  68. return ls::std::network::Socket::_bindUnix();
  69. #endif
  70. }
  71. bool ls::std::network::Socket::close()
  72. {
  73. return this->_close();
  74. }
  75. bool ls::std::network::Socket::connect()
  76. {
  77. #if LS_STD_UNIX_PLATFORM
  78. return ls::std::network::Socket::_connectUnix();
  79. #endif
  80. }
  81. bool ls::std::network::Socket::handle(const ls::std::core::type::connection_id &_connectionId)
  82. {
  83. return this->_handle(_connectionId);
  84. }
  85. bool ls::std::network::Socket::handle()
  86. {
  87. return this->_handle(1);
  88. }
  89. bool ls::std::network::Socket::isInitialized() const
  90. {
  91. return this->initialized;
  92. }
  93. bool ls::std::network::Socket::listen()
  94. {
  95. if (this->parameter.socketAddress.protocolType != LS_STD_PROTOCOL_TYPE_TCP)
  96. {
  97. throw ls::std::core::WrongProtocolException{};
  98. }
  99. #if LS_STD_UNIX_PLATFORM
  100. return ls::std::network::Socket::_listenUnix();
  101. #endif
  102. }
  103. #if LS_STD_UNIX_PLATFORM
  104. ls::std::core::type::connection_id ls::std::network::Socket::_acceptUnix()
  105. {
  106. ::sockaddr_in incoming{};
  107. ::socklen_t length{};
  108. ls::std::core::type::connection_id acceptedDescriptor = this->parameter.posixSocket->accept(this->unixDescriptors.at(1), reinterpret_cast<sockaddr *>(&incoming), &length);
  109. if (acceptedDescriptor >= 0)
  110. {
  111. this->_addUnixDescriptor(acceptedDescriptor);
  112. }
  113. else
  114. {
  115. throw ls::std::core::SocketOperationFailedException{};
  116. }
  117. return this->unixUniqueDescriptorId;
  118. }
  119. void ls::std::network::Socket::_addUnixDescriptor(const int &_descriptor)
  120. {
  121. ++this->unixUniqueDescriptorId;
  122. this->unixDescriptors.insert({this->unixUniqueDescriptorId, _descriptor});
  123. }
  124. bool ls::std::network::Socket::_bindUnix()
  125. {
  126. ls::std::network::ConvertedSocketAddress convertedSocketAddress = ls::std::network::SocketAddressMapper::from(ls::std::network::Socket::_createSocketAddressMapperParameter());
  127. return this->parameter.posixSocket->bind(this->unixDescriptors.at(1), reinterpret_cast<const sockaddr *>(&convertedSocketAddress.socketAddressUnix), convertedSocketAddress.addressLength) == 0;
  128. }
  129. #endif
  130. bool ls::std::network::Socket::_close()
  131. {
  132. #if LS_STD_UNIX_PLATFORM
  133. return ls::std::network::Socket::_closeUnix(this->unixDescriptors.at(1));
  134. #endif
  135. }
  136. #if LS_STD_UNIX_PLATFORM
  137. bool ls::std::network::Socket::_closeUnix(const int& _descriptor)
  138. {
  139. return this->parameter.posixSocket->close(_descriptor) == 0;
  140. }
  141. bool ls::std::network::Socket::_connectUnix()
  142. {
  143. ls::std::network::ConvertedSocketAddress convertedSocketAddress = ls::std::network::SocketAddressMapper::from(ls::std::network::Socket::_createSocketAddressMapperParameter());
  144. return this->parameter.posixSocket->connect(this->unixDescriptors.at(1), reinterpret_cast<const sockaddr *>(&convertedSocketAddress.socketAddressUnix), convertedSocketAddress.addressLength) == 0;
  145. }
  146. #endif
  147. ls::std::network::SocketAddressMapperParameter ls::std::network::Socket::_createSocketAddressMapperParameter() const
  148. {
  149. ls::std::network::SocketAddressMapperParameter mapperParameter{};
  150. mapperParameter.socketAddress = this->parameter.socketAddress;
  151. mapperParameter.protocolFamilyType = this->parameter.protocolFamilyType;
  152. return mapperParameter;
  153. }
  154. bool ls::std::network::Socket::_hasAcceptedConnection(const ls::std::core::type::connection_id &_connectionId)
  155. {
  156. #if LS_STD_UNIX_PLATFORM
  157. return this->_hasAcceptedConnectionUnix(_connectionId);
  158. #endif
  159. }
  160. #if LS_STD_UNIX_PLATFORM
  161. bool ls::std::network::Socket::_hasAcceptedConnectionUnix(const ls::std::core::type::connection_id &_connectionId)
  162. {
  163. return this->unixDescriptors.find(_connectionId) != this->unixDescriptors.end();
  164. }
  165. #endif
  166. bool ls::std::network::Socket::_handle(const ls::std::core::type::connection_id& _connectionId)
  167. {
  168. bool focusSet{};
  169. if (this->_hasAcceptedConnection(_connectionId))
  170. {
  171. this->currentAcceptedConnection = _connectionId;
  172. focusSet = true;
  173. }
  174. return focusSet;
  175. }
  176. void ls::std::network::Socket::_init()
  177. {
  178. #if LS_STD_UNIX_PLATFORM
  179. this->initialized = ls::std::network::Socket::_initUnix();
  180. #endif
  181. }
  182. void ls::std::network::Socket::_initReadBuffer()
  183. {
  184. if (this->parameter.readBufferSize <= 0)
  185. {
  186. throw ls::std::core::IllegalArgumentException{};
  187. }
  188. this->readBuffer = new ls::std::core::type::byte[this->parameter.readBufferSize];
  189. }
  190. #if LS_STD_UNIX_PLATFORM
  191. bool ls::std::network::Socket::_initUnix()
  192. {
  193. this->_setPosixReaderApi();
  194. this->_setPosixSocketApi();
  195. this->_setPosixWriterApi();
  196. ls::std::network::ConvertedProtocolFamily convertedProtocolFamily = ls::std::network::ProtocolFamilyMapper::from(this->parameter.protocolFamilyType);
  197. ls::std::network::Protocol protocol = ls::std::network::ProtocolMapper::from(this->parameter.socketAddress.protocolType);
  198. int descriptor = this->parameter.posixSocket->create(convertedProtocolFamily.unixDomain, protocol.unixProtocol, 0);
  199. bool success = descriptor != -1;
  200. if (success)
  201. {
  202. this->_addUnixDescriptor(descriptor);
  203. this->currentAcceptedConnection = 1;
  204. }
  205. return success;
  206. }
  207. bool ls::std::network::Socket::_listenUnix()
  208. {
  209. return this->parameter.posixSocket->listen(this->unixDescriptors.at(1), this->parameter.queueSize) == 0;
  210. }
  211. #endif
  212. ls::std::core::type::byte_field ls::std::network::Socket::_read()
  213. {
  214. #if LS_STD_UNIX_PLATFORM
  215. return this->_readUnix(this->unixDescriptors.at(this->currentAcceptedConnection));
  216. #endif
  217. }
  218. #if LS_STD_UNIX_PLATFORM
  219. ls::std::core::type::byte_field ls::std::network::Socket::_readUnix(const int& _descriptor)
  220. {
  221. size_t size = this->parameter.posixReader->read(_descriptor, this->readBuffer, this->parameter.readBufferSize);
  222. if (size == -1)
  223. {
  224. throw ls::std::core::FileOperationException{};
  225. }
  226. return ls::std::core::type::byte_field{this->readBuffer, size};
  227. }
  228. void ls::std::network::Socket::_setPosixReaderApi()
  229. {
  230. if (this->parameter.posixReader == nullptr)
  231. {
  232. this->parameter.posixReader = ::std::make_shared<ls::std::common::api::PosixReader>();
  233. }
  234. }
  235. void ls::std::network::Socket::_setPosixSocketApi()
  236. {
  237. if (this->parameter.posixSocket == nullptr)
  238. {
  239. this->parameter.posixSocket = ::std::make_shared<ls::std::common::api::PosixSocket>();
  240. }
  241. }
  242. void ls::std::network::Socket::_setPosixWriterApi()
  243. {
  244. if (this->parameter.posixWriter == nullptr)
  245. {
  246. this->parameter.posixWriter = ::std::make_shared<ls::std::common::api::PosixWriter>();
  247. }
  248. }
  249. #endif
  250. bool ls::std::network::Socket::_write(const ls::std::core::type::byte_field &_data)
  251. {
  252. #if LS_STD_UNIX_PLATFORM
  253. return this->_writeUnix(this->unixDescriptors.at(this->currentAcceptedConnection), _data);
  254. #endif
  255. }
  256. #if LS_STD_UNIX_PLATFORM
  257. bool ls::std::network::Socket::_writeUnix(const int& _descriptor, const ls::std::core::type::byte_field &_data)
  258. {
  259. bool written{};
  260. if (!_data.empty())
  261. {
  262. size_t size = _data.size() + 1;
  263. char* buffer = new char[size];
  264. ::std::strcpy(buffer, _data.c_str());
  265. written = this->parameter.posixWriter->write(_descriptor, buffer, size) != -1;
  266. delete[] buffer;
  267. }
  268. return written;
  269. }
  270. #endif