Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

170 lines
3.6 KiB

  1. //========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #if defined(_WIN32) && !defined(_X360)
  7. #include <winsock.h>
  8. #elif defined( _PS3 )
  9. #include "blockingudpsocket.h"
  10. #elif POSIX
  11. #define INVALID_SOCKET -1
  12. #define SOCKET_ERROR -1
  13. #include <sys/types.h>
  14. #include <sys/socket.h>
  15. #include <netinet/in.h>
  16. #include <unistd.h>
  17. #define closesocket close
  18. #endif
  19. #include "blockingudpsocket.h"
  20. // NOTE: This has to be the last file included!
  21. #include "tier0/memdbgon.h"
  22. #ifdef _PS3
  23. CBlockingUDPSocket::CBlockingUDPSocket() : m_pImpl( NULL ), m_Socket( 0 ) {}
  24. CBlockingUDPSocket::~CBlockingUDPSocket() {}
  25. bool CBlockingUDPSocket::WaitForMessage( float timeOutInSeconds ) { return false; }
  26. unsigned int CBlockingUDPSocket::ReceiveSocketMessage( struct sockaddr_in *packet_from, unsigned char *buf, size_t bufsize ) { return 0; }
  27. bool CBlockingUDPSocket::SendSocketMessage( const struct sockaddr_in& rRecipient, const unsigned char *buf, size_t bufsize ) { return false; }
  28. bool CBlockingUDPSocket::CreateSocket (void) { return false; }
  29. #else
  30. class CBlockingUDPSocket::CImpl
  31. {
  32. public:
  33. struct sockaddr_in m_SocketIP;
  34. fd_set m_FDSet;
  35. };
  36. CBlockingUDPSocket::CBlockingUDPSocket() :
  37. m_cserIP(),
  38. m_Socket( 0 ),
  39. m_pImpl( new CImpl )
  40. {
  41. CreateSocket();
  42. }
  43. CBlockingUDPSocket::~CBlockingUDPSocket()
  44. {
  45. delete m_pImpl;
  46. closesocket( static_cast<unsigned int>( m_Socket ));
  47. }
  48. bool CBlockingUDPSocket::CreateSocket (void)
  49. {
  50. struct sockaddr_in address;
  51. m_Socket = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP );
  52. if ( m_Socket == INVALID_SOCKET )
  53. {
  54. return false;
  55. }
  56. address = m_pImpl->m_SocketIP;
  57. if ( SOCKET_ERROR == bind( m_Socket, ( struct sockaddr * )&address, sizeof( address ) ) )
  58. {
  59. return false;
  60. }
  61. #ifdef _WIN32
  62. if ( m_pImpl->m_SocketIP.sin_addr.S_un.S_addr == INADDR_ANY )
  63. {
  64. m_pImpl->m_SocketIP.sin_addr.S_un.S_addr = 0L;
  65. }
  66. #elif POSIX
  67. if ( m_pImpl->m_SocketIP.sin_addr.s_addr == INADDR_ANY )
  68. {
  69. m_pImpl->m_SocketIP.sin_addr.s_addr = 0L;
  70. }
  71. #endif
  72. return true;
  73. }
  74. bool CBlockingUDPSocket::WaitForMessage( float timeOutInSeconds )
  75. {
  76. struct timeval tv;
  77. FD_ZERO( &m_pImpl->m_FDSet );
  78. FD_SET( m_Socket, &m_pImpl->m_FDSet );//lint !e717
  79. tv.tv_sec = (int)timeOutInSeconds;
  80. float remainder = timeOutInSeconds - (int)timeOutInSeconds;
  81. tv.tv_usec = (int)( remainder * 1000000 + 0.5f ); /* micro seconds */
  82. if ( SOCKET_ERROR == select( ( int )m_Socket + 1, &m_pImpl->m_FDSet, NULL, NULL, &tv ) )
  83. {
  84. return false;
  85. }
  86. if ( FD_ISSET( m_Socket, &m_pImpl->m_FDSet) )
  87. {
  88. return true;
  89. }
  90. // Timed out
  91. return false;
  92. }
  93. unsigned int CBlockingUDPSocket::ReceiveSocketMessage( struct sockaddr_in *packet_from, unsigned char *buf, size_t bufsize )
  94. {
  95. memset( packet_from, 0, sizeof( *packet_from ) );
  96. struct sockaddr fromaddress;
  97. int fromlen = sizeof( fromaddress );
  98. int packet_length = recvfrom
  99. (
  100. m_Socket,
  101. (char *)buf,
  102. (int)bufsize,
  103. 0,
  104. &fromaddress,
  105. (socklen_t *)&fromlen
  106. );
  107. if ( SOCKET_ERROR == packet_length )
  108. {
  109. return 0;
  110. }
  111. // In case it's parsed as a string
  112. buf[ packet_length ] = 0;
  113. // Copy over the receive address
  114. *packet_from = *( struct sockaddr_in * )&fromaddress;
  115. return ( unsigned int )packet_length;
  116. }
  117. bool CBlockingUDPSocket::SendSocketMessage( const struct sockaddr_in & rRecipient, const unsigned char *buf, size_t bufsize )
  118. {
  119. // Send data
  120. int bytesSent = sendto
  121. (
  122. m_Socket,
  123. (const char *)buf,
  124. (int)bufsize,
  125. 0,
  126. reinterpret_cast< const sockaddr * >( &rRecipient ),
  127. sizeof( rRecipient )
  128. );
  129. if ( SOCKET_ERROR == bytesSent )
  130. {
  131. return false;
  132. }
  133. return true;
  134. }
  135. #endif