PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/source/Network/Socket.cpp

http://github.com/ungerik/BaseLib
C++ | 778 lines | 556 code | 171 blank | 51 comment | 96 complexity | 691bc188ef18497107250197153ae714 MD5 | raw file
  1. /******************************************************************************
  2. Developed and Copyright (c) by
  3. Erik Unger
  4. Contact: erik@erikunger.com
  5. ******************************************************************************/
  6. #include "BaseLib/Network/Socket.h"
  7. #include "BaseLib/Buffers/AbstractBinaryBuffer.h"
  8. #include "BaseLib/intern/Errors.h"
  9. #include "BaseLib/Streams/InputStream.h"
  10. #include "BaseLib/Utilities/AutoArray.h"
  11. namespace BaseLib {
  12. namespace Network {
  13. using namespace BaseLib::Buffers;
  14. using namespace BaseLib::System;
  15. using namespace BaseLib::ErrorHandling;
  16. using namespace BaseLib::Functors;
  17. using namespace BaseLib::Utilities;
  18. using BaseLib::Utilities::AutoArray;
  19. class BinarySocketBuffer : public DefaultBinaryBuffer {
  20. public:
  21. BinarySocketBuffer() {}
  22. explicit BinarySocketBuffer(Socket* newSocket)
  23. : DefaultBinaryBuffer(false)
  24. , socket(newSocket)
  25. , readTimeoutSeconds(0.0)
  26. {
  27. BL_ASSERT(socket != NULL);
  28. }
  29. virtual void close()
  30. {
  31. socket->close();
  32. }
  33. virtual int readFromCurrentPosition(void* destination, int byteCount, bool moveCurrentPos = true)
  34. {
  35. return socket->receive(destination, byteCount);
  36. }
  37. virtual bool readCompleteFromCurrentPosition(void* destination, int byteCount, bool moveCurrentPos)
  38. {
  39. if (readTimeoutSeconds == 0.0)
  40. {
  41. if (readFromCurrentPositionPossible() == true)
  42. {
  43. if (readFromCurrentPosition(destination, byteCount) != byteCount)
  44. {
  45. ioError("");
  46. return false;
  47. }
  48. return true;
  49. }
  50. else
  51. {
  52. return false;
  53. }
  54. }
  55. else
  56. {
  57. double timeout = readTimeoutSeconds;
  58. int bytesToRead = byteCount;
  59. const double endTime = Time::nowInSeconds() + timeout;
  60. AutoArray<int8> buffer(new int8[byteCount]);
  61. do
  62. {
  63. bytesToRead -= readFromCurrentPosition(buffer, bytesToRead);
  64. timeout = endTime - Time::nowInSeconds();
  65. if (timeout > 0.0) Thread::sleepSeconds(0.01);
  66. }
  67. while (bytesToRead > 0 && timeout > 0.0);
  68. if (bytesToRead == 0)
  69. {
  70. memCopy(destination, buffer, byteCount);
  71. return true;
  72. }
  73. else
  74. {
  75. return false;
  76. }
  77. }
  78. }
  79. virtual int writeAtPosition(int64 positionInBytes, const void* source, int byteCount) // position is ignored
  80. {
  81. return socket->send(source, byteCount);
  82. }
  83. virtual double getTimeoutForNextRead() const
  84. {
  85. return readTimeoutSeconds;
  86. }
  87. virtual void setTimeoutForNextRead(double newReadTimeoutSeconds)
  88. {
  89. BL_ASSERT(newReadTimeoutSeconds >= 0.0);
  90. readTimeoutSeconds = newReadTimeoutSeconds;
  91. }
  92. virtual void setCurrentPosition(int newCurrentPosition) // position is ignored
  93. {
  94. }
  95. virtual int64 availableBytesFromCurrentPosition() const
  96. {
  97. return socket->getBytesAvailable();
  98. }
  99. private:
  100. Socket* socket;
  101. double readTimeoutSeconds; ///
  102. };
  103. ///////////////////////////////////////////////////////////////////////////////
  104. Socket::Socket(ProtocolType newProtocolType, uint16 bindToPort)
  105. : protocolType(newProtocolType)
  106. , handle(INVALID_SOCKET)
  107. , port(0)
  108. , readTimeoutSeconds(0.0)
  109. , binarySocketBuffer(NULL)
  110. , binaryInputStream(NULL)
  111. , binaryOutputStream(NULL)
  112. , stringEncoding(BinaryStreamEncoding::STRING_IMPLEMENTATION)
  113. , endian(BinaryStreamEncoding::STREAM_IS_SMALL_ENDIAN)
  114. , acceptThread(NULL)
  115. , acceptCallbackFunctor(NULL)
  116. , acceptAsynchronResult(NULL)
  117. , blocking(true)
  118. {
  119. useBaseLibNetworking();
  120. if (protocolType == TCP)
  121. {
  122. handle = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  123. }
  124. else
  125. {
  126. BL_ASSERT(protocolType == UDP);
  127. handle = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
  128. }
  129. if (handle != INVALID_SOCKET)
  130. {
  131. if (bindToPort != 0)
  132. {
  133. bind(bindToPort);
  134. }
  135. }
  136. else
  137. {
  138. ioError(LAST_SOCKET_ERROR);
  139. }
  140. }
  141. Socket::Socket(int newHandle, ProtocolType newProtocolType)
  142. : protocolType(newProtocolType)
  143. , handle(newHandle)
  144. , port(0)
  145. , readTimeoutSeconds(0.0)
  146. , binarySocketBuffer(NULL)
  147. , binaryInputStream(NULL)
  148. , binaryOutputStream(NULL)
  149. , stringEncoding(BinaryStreamEncoding::STRING_IMPLEMENTATION)
  150. , endian(BinaryStreamEncoding::STREAM_IS_SMALL_ENDIAN)
  151. , acceptThread(NULL)
  152. , acceptCallbackFunctor(NULL)
  153. , acceptAsynchronResult(NULL)
  154. , blocking(true)
  155. {
  156. useBaseLibNetworking();
  157. }
  158. Socket::~Socket()
  159. {
  160. delete binarySocketBuffer;
  161. close();
  162. }
  163. void Socket::close()
  164. {
  165. if (isHandleValid() == true)
  166. {
  167. if (closesocket(handle) != 0)
  168. {
  169. ioError(LAST_SOCKET_ERROR);
  170. }
  171. handle = INVALID_SOCKET;
  172. releaseBaseLibNetworking();
  173. }
  174. }
  175. void Socket::bind(uint16 portNumber)
  176. {
  177. sockaddr_in addr;
  178. addr.sin_family = AF_INET;
  179. addr.sin_port = bigEndian(portNumber);
  180. addr.sin_addr.s_addr = INADDR_ANY;
  181. memset(&addr.sin_zero, 0, sizeof(addr.sin_zero));
  182. if (::bind(handle, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == 0)
  183. {
  184. port = portNumber;
  185. }
  186. else
  187. {
  188. ioError(LAST_SOCKET_ERROR);
  189. }
  190. }
  191. bool Socket::connect(const IpAddress& ipAddress)
  192. {
  193. sockaddr addr;
  194. return (::connect(handle, ipAddress.makeSockAddr(addr), sizeof(addr)) == 0);
  195. }
  196. IpAddress Socket::getAddress() const
  197. {
  198. sockaddr addr;
  199. int len = sizeof(addr);
  200. if (getsockname(handle, &addr, &len) == 0)
  201. {
  202. return addr;
  203. }
  204. else
  205. {
  206. return IpAddress();
  207. }
  208. }
  209. IpAddress Socket::getPeerAddress() const
  210. {
  211. sockaddr addr;
  212. int len = sizeof(addr);
  213. if (getpeername(handle, &addr, &len) == 0)
  214. {
  215. return addr;
  216. }
  217. else
  218. {
  219. return IpAddress();
  220. }
  221. }
  222. void Socket::listen()
  223. {
  224. if (::listen(handle, SOMAXCONN) != 0)
  225. {
  226. ioError(LAST_SOCKET_ERROR);
  227. }
  228. }
  229. //void Socket::listenAsynchron()
  230. //{
  231. // listenAsynchronCallbackFunctor = NULL;
  232. // listenThread = Thread::create(this, &Socket::listenAsynchronThreadFunction);
  233. //}
  234. //
  235. //
  236. //
  237. //void Socket::listenAsynchron(const CallbackFunctor& callbackFunctor)
  238. //{
  239. // listenAsynchronCallbackFunctor = callbackFunctor.clone();
  240. // listenThread = Thread::create(this, &Socket::listenAsynchronThreadFunction);
  241. //}
  242. //
  243. //
  244. //
  245. //
  246. //void Socket::listenAsynchronThreadFunction()
  247. //{
  248. // listen();
  249. // listenThread = NULL;
  250. // if (listenAsynchronCallbackFunctor != NULL)
  251. // {
  252. // (*listenAsynchronCallbackFunctor)();
  253. // listenAsynchronCallbackFunctor = NULL;
  254. // }
  255. //}
  256. //
  257. //
  258. //
  259. //bool Socket::isListeningAsynchron() const
  260. //{
  261. // return listenThread != NULL;
  262. //}
  263. //
  264. //
  265. //
  266. //void Socket::endListenAsynchron()
  267. //{
  268. // listenThread = NULL;
  269. //}
  270. Socket* Socket::accept()
  271. {
  272. const int newHandle = ::accept(handle, NULL, NULL);
  273. if (newHandle != INVALID_SOCKET)
  274. {
  275. return new Socket(newHandle, protocolType);
  276. }
  277. else
  278. {
  279. ioError(LAST_SOCKET_ERROR);
  280. return NULL;
  281. }
  282. }
  283. void Socket::acceptAsynchron()
  284. {
  285. acceptCallbackFunctor = NULL;
  286. acceptThread = new Thread(MethodFunctor0<Socket, void>(this, &Socket::acceptAsynchronThreadFunction)); // TODO: Optmieren
  287. }
  288. void Socket::acceptAsynchron(const AcceptCallbackFunctor& callbackFunctor)
  289. {
  290. acceptCallbackFunctor = callbackFunctor.clone();
  291. acceptThread = new Thread(MethodFunctor0<Socket, void>(this, &Socket::acceptAsynchronThreadFunction)); // TODO: Optmieren
  292. }
  293. void Socket::acceptAsynchronThreadFunction()
  294. {
  295. acceptAsynchronResult = accept();
  296. acceptThread = NULL;
  297. if (acceptCallbackFunctor != NULL)
  298. {
  299. (*acceptCallbackFunctor)(acceptAsynchronResult);
  300. }
  301. }
  302. int Socket::send(const void* source, int bytesToSend) const
  303. {
  304. BL_ASSERT(bytesToSend >= 0);
  305. const int bytesSent = ::send(handle, static_cast<const char*>(source), bytesToSend, 0);
  306. if (bytesSent != SOCKET_ERROR)
  307. {
  308. return bytesSent;
  309. }
  310. else
  311. {
  312. ioError(LAST_SOCKET_ERROR);
  313. return 0;
  314. }
  315. }
  316. void Socket::sendAll(const void* source, int bytesToSend, double timeout) const
  317. {
  318. BL_ASSERT(bytesToSend >= 0);
  319. BL_ASSERT(timeout >= 0.0);
  320. const double endTime = Time::nowInSeconds() + timeout;
  321. int bytesSent = send(source, bytesToSend);
  322. if (bytesSent != bytesToSend)
  323. {
  324. BL_ASSERT(bytesSent < bytesToSend);
  325. bytesSent = send(source, bytesToSend);
  326. source = offsetPointer(source, bytesSent);
  327. bytesToSend -= bytesSent;
  328. do
  329. {
  330. if (Time::nowInSeconds() > endTime)
  331. {
  332. ioError(SOCKET_SEND_TIMEOUT);
  333. return;
  334. }
  335. bytesSent = send(source, bytesToSend);
  336. source = offsetPointer(source, bytesSent);
  337. bytesToSend -= bytesSent;
  338. }
  339. while (bytesSent < bytesToSend);
  340. }
  341. }
  342. int Socket::getBytesAvailable(double timeout) const
  343. {
  344. int result = getBytesAvailable();
  345. if (result == 0 && timeout > 0.0)
  346. {
  347. const double endTime = Time::nowInSeconds() + timeout;
  348. do
  349. {
  350. Thread::sleepSeconds(0.01);
  351. result = getBytesAvailable();
  352. timeout = endTime - Time::nowInSeconds();
  353. }
  354. while (result == 0 && timeout > 0.0);
  355. }
  356. return result;
  357. }
  358. int Socket::receive(void* destination, int destinationSize, double timeout) const
  359. {
  360. BL_ASSERT(destinationSize >= 0);
  361. BL_ASSERT(timeout >= 0.0);
  362. if (destinationSize == 0) return 0;
  363. getBytesAvailable(timeout);
  364. const int bytesRead = recv(handle, static_cast<char*>(destination), destinationSize, 0);
  365. if (bytesRead != SOCKET_ERROR)
  366. {
  367. return bytesRead;
  368. }
  369. else
  370. {
  371. ioError(LAST_SOCKET_ERROR);
  372. return 0;
  373. }
  374. }
  375. int Socket::peek(void* destination, int destinationSize) const
  376. {
  377. BL_ASSERT(destinationSize >= 0);
  378. if (destinationSize == 0) return 0;
  379. const int bytesRead = recv(handle, static_cast<char*>(destination), destinationSize, MSG_PEEK);
  380. if (bytesRead != SOCKET_ERROR)
  381. {
  382. return bytesRead;
  383. }
  384. else
  385. {
  386. ioError(LAST_SOCKET_ERROR);
  387. return 0;
  388. }
  389. }
  390. int Socket::sendTo(const void* source, int bytesToSend, const IpAddress& toAddress) const
  391. {
  392. BL_ASSERT(bytesToSend >= 0);
  393. sockaddr addr;
  394. const int bytesSent = ::sendto(handle, static_cast<const char*>(source), bytesToSend, 0, toAddress.makeSockAddr(addr), sizeof(addr));
  395. if (bytesSent != SOCKET_ERROR)
  396. {
  397. return bytesSent;
  398. }
  399. else
  400. {
  401. ioError(LAST_SOCKET_ERROR);
  402. return 0;
  403. }
  404. }
  405. void Socket::sendAllTo(const void* source, int bytesToSend, const IpAddress& toAddress, double timeout) const
  406. {
  407. BL_ASSERT(bytesToSend >= 0);
  408. BL_ASSERT(timeout >= 0.0);
  409. const double endTime = Time::nowInSeconds() + timeout;
  410. int bytesSent = sendTo(source, bytesToSend, toAddress);
  411. if (bytesSent != bytesToSend)
  412. {
  413. BL_ASSERT(bytesSent < bytesToSend);
  414. bytesSent = sendTo(source, bytesToSend, toAddress);
  415. source = offsetPointer(source, bytesSent);
  416. bytesToSend -= bytesSent;
  417. do
  418. {
  419. if (Time::nowInSeconds() > endTime)
  420. {
  421. ioError(SOCKET_SEND_TIMEOUT);
  422. return;
  423. }
  424. bytesSent = sendTo(source, bytesToSend, toAddress);
  425. source = offsetPointer(source, bytesSent);
  426. bytesToSend -= bytesSent;
  427. }
  428. while (bytesSent < bytesToSend);
  429. }
  430. }
  431. int Socket::receiveFrom(void* destination, int destinationSize, IpAddress& fromAddress, double timeout) const
  432. {
  433. BL_ASSERT(destinationSize > 0);
  434. BL_ASSERT(timeout >= 0.0);
  435. if (getBytesAvailable() == 0 && timeout > 0.0)
  436. {
  437. const double endTime = Time::nowInSeconds() + timeout;
  438. do
  439. {
  440. Thread::sleepSeconds(0.01);
  441. if (Time::nowInSeconds() >= endTime) return 0;
  442. }
  443. while (getBytesAvailable() == 0);
  444. }
  445. sockaddr addr;
  446. int addrLen = sizeof(addr);
  447. const int bytesRead = recvfrom(handle, static_cast<char *>(destination), destinationSize, 0, &addr, &addrLen);
  448. if (bytesRead != SOCKET_ERROR)
  449. {
  450. fromAddress = addr;
  451. return bytesRead;
  452. }
  453. else
  454. {
  455. ioError(LAST_SOCKET_ERROR);
  456. return 0;
  457. }
  458. }
  459. int Socket::peekFrom(void* destination, int destinationSize, IpAddress& fromAddress) const
  460. {
  461. BL_ASSERT(destinationSize > 0);
  462. sockaddr addr;
  463. int addrLen = sizeof(addr);
  464. const int bytesRead = recvfrom(handle, static_cast<char *>(destination), destinationSize, MSG_PEEK, &addr, &addrLen);
  465. if (bytesRead != SOCKET_ERROR)
  466. {
  467. fromAddress = addr;
  468. return bytesRead;
  469. }
  470. else
  471. {
  472. ioError(LAST_SOCKET_ERROR);
  473. return 0;
  474. }
  475. }
  476. BinaryInputStream& Socket::inputStream()
  477. {
  478. if (binaryInputStream == NULL)
  479. {
  480. if (binarySocketBuffer == NULL) binarySocketBuffer = new BinarySocketBuffer(this);
  481. binaryInputStream = new BinaryInputStream(*binarySocketBuffer);
  482. }
  483. return *binaryInputStream;
  484. }
  485. BinaryOutputStream& Socket::outputStream()
  486. {
  487. if (binaryOutputStream == NULL)
  488. {
  489. if (binarySocketBuffer == NULL) binarySocketBuffer = new BinarySocketBuffer(this);
  490. binaryOutputStream = new BinaryOutputStream(*binarySocketBuffer);
  491. }
  492. return *binaryOutputStream;
  493. }
  494. const BinaryInputStream& Socket::inputStream() const
  495. {
  496. return const_cast<Socket*>(this)->inputStream();
  497. }
  498. const BinaryOutputStream& Socket::outputStream() const
  499. {
  500. return const_cast<Socket*>(this)->outputStream();
  501. }
  502. void Socket::setReadTimeoutSeconds(double newReadTimeoutSeconds)
  503. {
  504. BL_ASSERT(newReadTimeoutSeconds >= 0.0);
  505. readTimeoutSeconds = newReadTimeoutSeconds;
  506. }
  507. int Socket::getBytesAvailable() const
  508. {
  509. unsigned long byteCount;
  510. return (ioctlsocket(handle, FIONREAD, &byteCount) == 0) ? byteCount : 0;
  511. }
  512. int Socket::getMaxMessageSize() const
  513. {
  514. int size;
  515. int optionSize = sizeof(size);
  516. if (getsockopt(handle, SOL_SOCKET, SO_MAX_MSG_SIZE, (char *)&size, &optionSize) == 0)
  517. {
  518. return size;
  519. }
  520. else
  521. {
  522. ioError(LAST_SOCKET_ERROR);
  523. return 0;
  524. }
  525. }
  526. int Socket::getReceiveBufferSize() const
  527. {
  528. int size;
  529. int optionSize = sizeof(size);
  530. if (getsockopt(handle, SOL_SOCKET, SO_RCVBUF, (char *)&size, &optionSize) == 0)
  531. {
  532. return size;
  533. }
  534. else
  535. {
  536. ioError(LAST_SOCKET_ERROR);
  537. return 0;
  538. }
  539. }
  540. bool Socket::setReceiveBufferSize(int size)
  541. {
  542. BL_ASSERT(size > 0);
  543. return (setsockopt(handle, SOL_SOCKET, SO_RCVBUF, (const char *)&size, sizeof(size)) == 0);
  544. }
  545. int Socket::getSendBufferSize() const
  546. {
  547. int size;
  548. int optionSize = sizeof(size);
  549. if (getsockopt(handle, SOL_SOCKET, SO_SNDBUF, (char *)&size, &optionSize) == 0)
  550. {
  551. return size;
  552. }
  553. else
  554. {
  555. ioError(LAST_SOCKET_ERROR);
  556. return 0;
  557. }
  558. }
  559. bool Socket::setSendBufferSize(int size)
  560. {
  561. BL_ASSERT(size > 0);
  562. return (setsockopt(handle, SOL_SOCKET, SO_SNDBUF, (const char *)&size, sizeof(size)) == 0);
  563. }
  564. bool Socket::isBroadcastEnabled() const
  565. {
  566. int enabled;
  567. int optionSize = sizeof(enabled);
  568. if (getsockopt(handle, SOL_SOCKET, SO_BROADCAST, (char *)&enabled, &optionSize) == 0)
  569. {
  570. return (enabled != 0);
  571. }
  572. else
  573. {
  574. ioError(LAST_SOCKET_ERROR);
  575. return false;
  576. }
  577. }
  578. void Socket::setBroadcastEnabled(bool enableBroadcast)
  579. {
  580. int enable = enableBroadcast;
  581. if (setsockopt(handle, SOL_SOCKET, SO_BROADCAST, (const char *)&enable, sizeof(enable)) != 0)
  582. {
  583. ioError(LAST_SOCKET_ERROR);
  584. }
  585. }
  586. bool Socket::isBlocking() const
  587. {
  588. return blocking;
  589. }
  590. void Socket::setBlocking(bool enableBlocking)
  591. {
  592. unsigned long enable = enableBlocking;
  593. if (ioctlsocket(handle, FIONBIO, &enable) == 0)
  594. {
  595. blocking = enableBlocking;
  596. }
  597. else
  598. {
  599. ioError(LAST_SOCKET_ERROR);
  600. }
  601. }
  602. } // namespace Network
  603. } // namespace BaseLib