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.

253 lines
7.3KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCETICE project - Copyright 2009 by Lucio Asnaghi.
  4. JUCETICE is based around the JUCE library - "Jules' Utility Class Extensions"
  5. Copyright 2007 by Julian Storer.
  6. ------------------------------------------------------------------------------
  7. JUCE and JUCETICE can be redistributed and/or modified under the terms of
  8. the GNU General Public License, as published by the Free Software Foundation;
  9. either version 2 of the License, or (at your option) any later version.
  10. JUCE and JUCETICE are distributed in the hope that they will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with JUCE and JUCETICE; if not, visit www.gnu.org/licenses or write to
  16. Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  17. Boston, MA 02111-1307 USA
  18. ==============================================================================
  19. This file is based around Niall Moody's OSC/UDP library, but was modified to
  20. be more independent and modularized, using the best practices from JUCE.
  21. ==============================================================================
  22. */
  23. #ifdef WIN32
  24. #include <winsock.h>
  25. #else
  26. #include <sys/types.h>
  27. #include <sys/socket.h>
  28. #include <sys/select.h>
  29. #include <netinet/in.h>
  30. #include <netdb.h>
  31. #endif
  32. BEGIN_JUCE_NAMESPACE
  33. //==============================================================================
  34. UDPSocket::UDPSocket ()
  35. : port (0)
  36. {
  37. SocketSetup::getInstance();
  38. sock = socket (AF_INET, SOCK_DGRAM, 0);
  39. }
  40. UDPSocket::UDPSocket (const String& address, const short port)
  41. {
  42. this->address = address;
  43. this->port = port;
  44. SocketSetup::getInstance();
  45. sock = socket (AF_INET, SOCK_DGRAM, 0);
  46. }
  47. UDPSocket::~UDPSocket ()
  48. {
  49. #ifdef WIN32
  50. closesocket (sock);
  51. #else
  52. close (sock);
  53. #endif
  54. }
  55. //==============================================================================
  56. void UDPSocket::setAddress (const String& address)
  57. {
  58. this->address = address;
  59. }
  60. void UDPSocket::setPort (const short port)
  61. {
  62. this->port = port;
  63. }
  64. //==============================================================================
  65. void UDPSocket::bindSocket ()
  66. {
  67. sockaddr_in localAddress;
  68. localAddress.sin_family = AF_INET;
  69. localAddress.sin_port = htons(port);
  70. localAddress.sin_addr.s_addr = INADDR_ANY;
  71. memset (&(localAddress.sin_zero), 0, 8);
  72. bind (sock, (sockaddr *)(&localAddress), sizeof(sockaddr_in));
  73. }
  74. //==============================================================================
  75. void UDPSocket::sendData (char *data, const long size)
  76. {
  77. sockaddr_in destAddress;
  78. hostent *he = gethostbyname ((const char*) address.toUTF8());
  79. destAddress.sin_family = AF_INET;
  80. destAddress.sin_port = htons (port);
  81. /*destAddress.sin_addr = *((struct in_addr *)gethostbyaddr(inet_addr(address.c_str()),
  82. (address.length()+1),
  83. 0)->h_addr_list);*/
  84. /*tempint = inet_addr(address.c_str());
  85. destAddress.sin_addr = *(in_addr *)(&tempint);*/
  86. destAddress.sin_addr = *(in_addr *)he->h_addr;
  87. memset (&(destAddress.sin_zero), '\0', 8);
  88. sendto(sock,
  89. data,
  90. size,
  91. 0,
  92. reinterpret_cast<sockaddr *>(&destAddress),
  93. sizeof(sockaddr));
  94. }
  95. //==============================================================================
  96. char *UDPSocket::getData (long& size)
  97. {
  98. int bytesReceived = 0;
  99. timeval timeToWait;
  100. fd_set setToCheck;
  101. sockaddr_in receivedAddress;
  102. timeToWait.tv_sec = 0;
  103. timeToWait.tv_usec = 2500; // 1/4 of a second.
  104. FD_ZERO(&setToCheck);
  105. FD_SET(sock, &setToCheck);
  106. //Use select so that we can timeout to check if we're supposed to stop the
  107. //thread yet.
  108. #ifdef WIN32
  109. if(select(1, &setToCheck, NULL, NULL, &timeToWait) == SOCKET_ERROR)
  110. {
  111. switch(WSAGetLastError())
  112. {
  113. case WSANOTINITIALISED:
  114. strcpy(receiveBuffer, "Not Initialised");
  115. break;
  116. case WSAEFAULT:
  117. strcpy(receiveBuffer, "Fault");
  118. break;
  119. case WSAENETDOWN:
  120. strcpy(receiveBuffer, "Network subsystem has failed.");
  121. break;
  122. case WSAEINVAL:
  123. strcpy(receiveBuffer, "Invalid parameter.");
  124. break;
  125. case WSAEINTR:
  126. strcpy(receiveBuffer, "Blocking socket was cancelled.");
  127. break;
  128. case WSAEINPROGRESS:
  129. strcpy(receiveBuffer, "Blocking socket in progress.");
  130. break;
  131. case WSAENOTSOCK:
  132. strcpy(receiveBuffer, "Not a socket.");
  133. break;
  134. }
  135. size = -1;
  136. return receiveBuffer;
  137. }
  138. #else
  139. if (select((sock+1), &setToCheck, NULL, NULL, &timeToWait) == -1)
  140. {
  141. /*switch(errno)
  142. {
  143. case EBADF:
  144. strcpy(receiveBuffer, "Invalid file descriptor.");
  145. break;
  146. case EINTR:
  147. strcpy(receiveBuffer, "Non blocked signal was caught.");
  148. break;
  149. case EINVAL:
  150. strcpy(receiveBuffer, "Invalid time value.");
  151. break;
  152. case ENOMEM:
  153. strcpy(receiveBuffer, "Not enough memory.");
  154. break;
  155. }*/
  156. size = -1;
  157. return receiveBuffer;
  158. }
  159. #endif
  160. if(FD_ISSET(sock, &setToCheck))
  161. {
  162. size = sizeof(sockaddr_in);
  163. #ifndef WIN32
  164. bytesReceived = recvfrom(sock,
  165. receiveBuffer,
  166. (MaxBufferSize-1),
  167. 0,
  168. (sockaddr *)(&receivedAddress),
  169. (unsigned int *)(&size));
  170. #else
  171. bytesReceived = recvfrom(sock,
  172. receiveBuffer,
  173. (MaxBufferSize-1),
  174. 0,
  175. (sockaddr *)(&receivedAddress),
  176. (int *)(&size));
  177. #endif
  178. if(bytesReceived > 0)
  179. {
  180. size = bytesReceived;
  181. return receiveBuffer;
  182. }
  183. else
  184. {
  185. size = -1;
  186. strcpy(receiveBuffer, "Received an empty packet?");
  187. return receiveBuffer;
  188. }
  189. }
  190. else
  191. {
  192. size = -1;
  193. return 0;
  194. }
  195. }
  196. //==============================================================================
  197. SocketSetup *SocketSetup::getInstance()
  198. {
  199. static SocketSetup instance;
  200. return &instance;
  201. }
  202. SocketSetup::SocketSetup()
  203. {
  204. #ifdef WIN32
  205. WSADATA wsaData; // if this doesn't work
  206. WSAStartup(MAKEWORD(1, 1), &wsaData);
  207. #endif
  208. }
  209. SocketSetup::~SocketSetup()
  210. {
  211. #ifdef WIN32
  212. WSACleanup();
  213. #endif
  214. }
  215. END_JUCE_NAMESPACE