PageRenderTime 40ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/Socket.hpp

https://github.com/grfz/Socket
C++ Header | 176 lines | 122 code | 34 blank | 20 comment | 9 complexity | d5303ab2e57ee361a11568a24b79e10e MD5 | raw file
  1. /*
  2. * Socket.hpp
  3. * This file is part of VallauriSoft
  4. *
  5. * Copyright (C) 2012 - Comina, gnuze
  6. *
  7. * VallauriSoft is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * VallauriSoft is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with VallauriSoft. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. #ifndef _SOCKET_HPP_
  21. #define _SOCKET_HPP_
  22. #include <iostream>
  23. #include <sstream>
  24. #include <exception>
  25. #include <string>
  26. #include <stdlib.h>
  27. #include <arpa/inet.h>
  28. #define MAX_BUFFER 1024
  29. using namespace std;
  30. namespace Socket
  31. {
  32. typedef int Socket;
  33. typedef string Ip;
  34. typedef unsigned int Port;
  35. typedef string Data;
  36. typedef struct
  37. {
  38. Ip ip;
  39. Port port;
  40. }Address;
  41. typedef struct
  42. {
  43. Address address;
  44. Data data;
  45. }Datagram;
  46. struct sockaddr_in* to_sockaddr(Address* a)
  47. { struct sockaddr_in* ret;
  48. ret=(struct sockaddr_in*) malloc (sizeof(struct sockaddr_in));
  49. ret->sin_family = AF_INET;
  50. inet_aton(a->ip.c_str(),&(ret->sin_addr));
  51. ret->sin_port=htons(a->port);
  52. return ret;
  53. }
  54. Address* from_sockaddr(struct sockaddr_in* address)
  55. { Address* ret;
  56. ret=(Address*)malloc(sizeof(Address));
  57. ret->ip = inet_ntoa(address->sin_addr);
  58. ret->port = ntohs(address->sin_port);
  59. return ret;
  60. }
  61. class Exception
  62. {
  63. private:
  64. string _message;
  65. public:
  66. Exception(string error) { this->_message = error; }
  67. virtual const char* what() { return this->_message.c_str(); }
  68. };
  69. class UDP
  70. {
  71. private:
  72. Socket _socket_id;
  73. bool _binded;
  74. public:
  75. UDP(void);
  76. ~UDP(void);
  77. void close(void);
  78. void bind(Port port);
  79. void send(Ip ip, Port port, Data data);
  80. Datagram receive();
  81. };
  82. UDP::UDP(void)
  83. {
  84. this->_socket_id = socket(AF_INET, SOCK_DGRAM, 0);
  85. if (this->_socket_id == -1) throw Exception("[Constructor] Cannot create socket");
  86. this->_binded = false;
  87. }
  88. UDP::~UDP(void)
  89. {
  90. }
  91. void UDP::close(void)
  92. {
  93. shutdown(this->_socket_id, SHUT_RDWR);
  94. }
  95. void UDP::bind(Port port)
  96. {
  97. struct sockaddr_in address;
  98. address.sin_family = AF_INET;
  99. address.sin_addr.s_addr=htonl(INADDR_ANY);
  100. address.sin_port=htons(port);
  101. if (this->_binded)
  102. {
  103. this->close();
  104. this->_socket_id = socket(AF_INET, SOCK_DGRAM, 0);
  105. }
  106. // ::bind() calls the function bind() from <arpa/inet.h> (outside the namespace)
  107. if (::bind(this->_socket_id, (struct sockaddr*)&address, sizeof(struct sockaddr_in)) == -1)
  108. {
  109. stringstream error;
  110. error << "[listen_on_port] with [port=" << port << "] Cannot bind socket";
  111. throw Exception(error.str());
  112. }
  113. this->_binded = true;
  114. }
  115. void UDP::send(Ip ip, Port port, Data data)
  116. {
  117. struct sockaddr_in address;
  118. address.sin_family = AF_INET;
  119. address.sin_port = htons(port);
  120. inet_aton(ip.c_str(), &address.sin_addr);
  121. if (sendto(this->_socket_id, (void*)data.c_str(), data.length() + 1, 0, (struct sockaddr*)&address, sizeof(struct sockaddr_in)) == -1)
  122. {
  123. stringstream error;
  124. error << "[send] with [ip=" << ip << "] [port=" << port << "] [data=" << data << "] Cannot send";
  125. throw Exception(error.str());
  126. }
  127. }
  128. Datagram UDP::receive()
  129. {
  130. int size = sizeof(struct sockaddr_in);
  131. char *buffer = (char*)malloc(sizeof(char) * MAX_BUFFER);
  132. struct sockaddr_in address;
  133. Datagram ret;
  134. if (recvfrom(this->_socket_id, (void*)buffer, MAX_BUFFER, 0, (struct sockaddr*)&address, (socklen_t*)&size) == -1) throw Exception("[receive] Cannot receive");
  135. ret.data = buffer;
  136. ret.address.ip = inet_ntoa(address.sin_addr);
  137. ret.address.port = ntohs(address.sin_port);
  138. free(buffer);
  139. return ret;
  140. }
  141. }
  142. #endif // _SOCKET_HPP_