PageRenderTime 31ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/src/SFML/Network/Socket.cpp

http://github.com/LaurentGomila/SFML
C++ | 151 lines | 82 code | 25 blank | 44 comment | 19 complexity | a239f2a0b2fa945951550301233ad9f9 MD5 | raw file
  1. ////////////////////////////////////////////////////////////
  2. //
  3. // SFML - Simple and Fast Multimedia Library
  4. // Copyright (C) 2007-2019 Laurent Gomila (laurent@sfml-dev.org)
  5. //
  6. // This software is provided 'as-is', without any express or implied warranty.
  7. // In no event will the authors be held liable for any damages arising from the use of this software.
  8. //
  9. // Permission is granted to anyone to use this software for any purpose,
  10. // including commercial applications, and to alter it and redistribute it freely,
  11. // subject to the following restrictions:
  12. //
  13. // 1. The origin of this software must not be misrepresented;
  14. // you must not claim that you wrote the original software.
  15. // If you use this software in a product, an acknowledgment
  16. // in the product documentation would be appreciated but is not required.
  17. //
  18. // 2. Altered source versions must be plainly marked as such,
  19. // and must not be misrepresented as being the original software.
  20. //
  21. // 3. This notice may not be removed or altered from any source distribution.
  22. //
  23. ////////////////////////////////////////////////////////////
  24. ////////////////////////////////////////////////////////////
  25. // Headers
  26. ////////////////////////////////////////////////////////////
  27. #include <SFML/Network/Socket.hpp>
  28. #include <SFML/Network/SocketImpl.hpp>
  29. #include <SFML/System/Err.hpp>
  30. namespace sf
  31. {
  32. ////////////////////////////////////////////////////////////
  33. Socket::Socket(Type type) :
  34. m_type (type),
  35. m_socket (priv::SocketImpl::invalidSocket()),
  36. m_isBlocking(true)
  37. {
  38. }
  39. ////////////////////////////////////////////////////////////
  40. Socket::~Socket()
  41. {
  42. // Close the socket before it gets destructed
  43. close();
  44. }
  45. ////////////////////////////////////////////////////////////
  46. void Socket::setBlocking(bool blocking)
  47. {
  48. // Apply if the socket is already created
  49. if (m_socket != priv::SocketImpl::invalidSocket())
  50. priv::SocketImpl::setBlocking(m_socket, blocking);
  51. m_isBlocking = blocking;
  52. }
  53. ////////////////////////////////////////////////////////////
  54. bool Socket::isBlocking() const
  55. {
  56. return m_isBlocking;
  57. }
  58. ////////////////////////////////////////////////////////////
  59. SocketHandle Socket::getHandle() const
  60. {
  61. return m_socket;
  62. }
  63. ////////////////////////////////////////////////////////////
  64. void Socket::create()
  65. {
  66. // Don't create the socket if it already exists
  67. if (m_socket == priv::SocketImpl::invalidSocket())
  68. {
  69. SocketHandle handle = socket(PF_INET, m_type == Tcp ? SOCK_STREAM : SOCK_DGRAM, 0);
  70. if (handle == priv::SocketImpl::invalidSocket())
  71. {
  72. err() << "Failed to create socket" << std::endl;
  73. return;
  74. }
  75. create(handle);
  76. }
  77. }
  78. ////////////////////////////////////////////////////////////
  79. void Socket::create(SocketHandle handle)
  80. {
  81. // Don't create the socket if it already exists
  82. if (m_socket == priv::SocketImpl::invalidSocket())
  83. {
  84. // Assign the new handle
  85. m_socket = handle;
  86. // Set the current blocking state
  87. setBlocking(m_isBlocking);
  88. if (m_type == Tcp)
  89. {
  90. // Disable the Nagle algorithm (i.e. removes buffering of TCP packets)
  91. int yes = 1;
  92. if (setsockopt(m_socket, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char*>(&yes), sizeof(yes)) == -1)
  93. {
  94. err() << "Failed to set socket option \"TCP_NODELAY\" ; "
  95. << "all your TCP packets will be buffered" << std::endl;
  96. }
  97. // On Mac OS X, disable the SIGPIPE signal on disconnection
  98. #ifdef SFML_SYSTEM_MACOS
  99. if (setsockopt(m_socket, SOL_SOCKET, SO_NOSIGPIPE, reinterpret_cast<char*>(&yes), sizeof(yes)) == -1)
  100. {
  101. err() << "Failed to set socket option \"SO_NOSIGPIPE\"" << std::endl;
  102. }
  103. #endif
  104. }
  105. else
  106. {
  107. // Enable broadcast by default for UDP sockets
  108. int yes = 1;
  109. if (setsockopt(m_socket, SOL_SOCKET, SO_BROADCAST, reinterpret_cast<char*>(&yes), sizeof(yes)) == -1)
  110. {
  111. err() << "Failed to enable broadcast on UDP socket" << std::endl;
  112. }
  113. }
  114. }
  115. }
  116. ////////////////////////////////////////////////////////////
  117. void Socket::close()
  118. {
  119. // Close the socket
  120. if (m_socket != priv::SocketImpl::invalidSocket())
  121. {
  122. priv::SocketImpl::close(m_socket);
  123. m_socket = priv::SocketImpl::invalidSocket();
  124. }
  125. }
  126. } // namespace sf