sock.hpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. /*
  2. * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
  3. * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it 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. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. */
  19. #ifndef __PJPP_SOCK_HPP__
  20. #define __PJPP_SOCK_HPP__
  21. #include <pj/sock.h>
  22. #include <pj/string.h>
  23. class Pj_Event_Handler;
  24. //
  25. // Base class for address.
  26. //
  27. class Pj_Addr
  28. {
  29. };
  30. //
  31. // Internet address.
  32. //
  33. class Pj_Inet_Addr : public pj_sockaddr_in, public Pj_Addr
  34. {
  35. public:
  36. //
  37. // Get port number.
  38. //
  39. pj_uint16_t get_port_number() const
  40. {
  41. return pj_sockaddr_in_get_port(this);
  42. }
  43. //
  44. // Set port number.
  45. //
  46. void set_port_number(pj_uint16_t port)
  47. {
  48. sin_family = PJ_AF_INET;
  49. pj_sockaddr_in_set_port(this, port);
  50. }
  51. //
  52. // Get IP address.
  53. //
  54. pj_uint32_t get_ip_address() const
  55. {
  56. return pj_sockaddr_in_get_addr(this).s_addr;
  57. }
  58. //
  59. // Get address string.
  60. //
  61. const char *get_address() const
  62. {
  63. return pj_inet_ntoa(sin_addr);
  64. }
  65. //
  66. // Set IP address.
  67. //
  68. void set_ip_address(pj_uint32_t addr)
  69. {
  70. sin_family = PJ_AF_INET;
  71. pj_sockaddr_in_set_addr(this, addr);
  72. }
  73. //
  74. // Set address.
  75. //
  76. pj_status_t set_address(const pj_str_t *addr)
  77. {
  78. return pj_sockaddr_in_set_str_addr(this, addr);
  79. }
  80. //
  81. // Set address.
  82. //
  83. pj_status_t set_address(const char *addr)
  84. {
  85. pj_str_t s;
  86. return pj_sockaddr_in_set_str_addr(this, pj_cstr(&s, addr));
  87. }
  88. //
  89. // Compare for equality.
  90. //
  91. bool operator==(const Pj_Inet_Addr &rhs) const
  92. {
  93. return sin_family == rhs.sin_family &&
  94. sin_addr.s_addr == rhs.sin_addr.s_addr &&
  95. sin_port == rhs.sin_port;
  96. }
  97. private:
  98. //
  99. // Dummy length used in pj_ioqueue_recvfrom() etc
  100. //
  101. friend class Pj_Event_Handler;
  102. friend class Pj_Socket;
  103. friend class Pj_Sock_Stream;
  104. friend class Pj_Sock_Dgram;
  105. int addrlen_;
  106. };
  107. //
  108. // Socket base class.
  109. //
  110. // Note:
  111. // socket will not automatically be closed on destructor.
  112. //
  113. class Pj_Socket
  114. {
  115. public:
  116. //
  117. // Default constructor.
  118. //
  119. Pj_Socket()
  120. : sock_(PJ_INVALID_SOCKET)
  121. {
  122. }
  123. //
  124. // Initialize from a socket handle.
  125. //
  126. explicit Pj_Socket(pj_sock_t sock)
  127. : sock_(sock)
  128. {
  129. }
  130. //
  131. // Copy constructor.
  132. //
  133. Pj_Socket(const Pj_Socket &rhs)
  134. : sock_(rhs.sock_)
  135. {
  136. }
  137. //
  138. // Destructor will not close the socket.
  139. // You must call close() explicitly.
  140. //
  141. ~Pj_Socket()
  142. {
  143. }
  144. //
  145. // Set socket handle.
  146. //
  147. void set_handle(pj_sock_t sock)
  148. {
  149. sock_ = sock;
  150. }
  151. //
  152. // Get socket handle.
  153. //
  154. pj_sock_t get_handle() const
  155. {
  156. return sock_;
  157. }
  158. //
  159. // Get socket handle.
  160. //
  161. pj_sock_t& get_handle()
  162. {
  163. return sock_;
  164. }
  165. //
  166. // See if the socket is valid.
  167. //
  168. bool is_valid() const
  169. {
  170. return sock_ != PJ_INVALID_SOCKET;
  171. }
  172. //
  173. // Create the socket.
  174. //
  175. pj_status_t create(int af, int type, int proto)
  176. {
  177. return pj_sock_socket(af, type, proto, &sock_);
  178. }
  179. //
  180. // Bind socket.
  181. //
  182. pj_status_t bind(const Pj_Inet_Addr &addr)
  183. {
  184. return pj_sock_bind(sock_, &addr, sizeof(Pj_Inet_Addr));
  185. }
  186. //
  187. // Close socket.
  188. //
  189. pj_status_t close()
  190. {
  191. pj_sock_close(sock_);
  192. }
  193. //
  194. // Get peer socket name.
  195. //
  196. pj_status_t getpeername(Pj_Inet_Addr *addr)
  197. {
  198. return pj_sock_getpeername(sock_, addr, &addr->addrlen_);
  199. }
  200. //
  201. // getsockname
  202. //
  203. pj_status_t getsockname(Pj_Inet_Addr *addr)
  204. {
  205. return pj_sock_getsockname(sock_, addr, &addr->addrlen_);
  206. }
  207. //
  208. // getsockopt.
  209. //
  210. pj_status_t getsockopt(pj_uint16_t level, pj_uint16_t optname,
  211. void *optval, int *optlen)
  212. {
  213. return pj_sock_getsockopt(sock_, level, optname, optval, optlen);
  214. }
  215. //
  216. // setsockopt
  217. //
  218. pj_status_t setsockopt(pj_uint16_t level, pj_uint16_t optname,
  219. const void *optval, int optlen)
  220. {
  221. return pj_sock_setsockopt(sock_, level, optname, optval, optlen);
  222. }
  223. //
  224. // receive data.
  225. //
  226. pj_ssize_t recv(void *buf, pj_size_t len, int flag = 0)
  227. {
  228. pj_ssize_t bytes = len;
  229. if (pj_sock_recv(sock_, buf, &bytes, flag) != PJ_SUCCESS)
  230. return -1;
  231. return bytes;
  232. }
  233. //
  234. // send data.
  235. //
  236. pj_ssize_t send(const void *buf, pj_ssize_t len, int flag = 0)
  237. {
  238. pj_ssize_t bytes = len;
  239. if (pj_sock_send(sock_, buf, &bytes, flag) != PJ_SUCCESS)
  240. return -1;
  241. return bytes;
  242. }
  243. //
  244. // connect.
  245. //
  246. pj_status_t connect(const Pj_Inet_Addr &addr)
  247. {
  248. return pj_sock_connect(sock_, &addr, sizeof(Pj_Inet_Addr));
  249. }
  250. //
  251. // assignment.
  252. //
  253. Pj_Socket &operator=(const Pj_Socket &rhs)
  254. {
  255. sock_ = rhs.sock_;
  256. return *this;
  257. }
  258. protected:
  259. friend class Pj_Event_Handler;
  260. pj_sock_t sock_;
  261. };
  262. #if PJ_HAS_TCP
  263. //
  264. // Stream socket.
  265. //
  266. class Pj_Sock_Stream : public Pj_Socket
  267. {
  268. public:
  269. //
  270. // Default constructor.
  271. //
  272. Pj_Sock_Stream()
  273. {
  274. }
  275. //
  276. // Initialize from a socket handle.
  277. //
  278. explicit Pj_Sock_Stream(pj_sock_t sock)
  279. : Pj_Socket(sock)
  280. {
  281. }
  282. //
  283. // Copy constructor.
  284. //
  285. Pj_Sock_Stream(const Pj_Sock_Stream &rhs) : Pj_Socket(rhs)
  286. {
  287. }
  288. //
  289. // Assignment.
  290. //
  291. Pj_Sock_Stream &operator=(const Pj_Sock_Stream &rhs)
  292. {
  293. sock_ = rhs.sock_;
  294. return *this;
  295. }
  296. //
  297. // listen()
  298. //
  299. pj_status_t listen(int backlog = 5)
  300. {
  301. return pj_sock_listen(sock_, backlog);
  302. }
  303. //
  304. // blocking accept()
  305. //
  306. Pj_Sock_Stream accept(Pj_Inet_Addr *remote_addr = NULL)
  307. {
  308. pj_sock_t newsock;
  309. int *addrlen = remote_addr ? &remote_addr->addrlen_ : NULL;
  310. pj_status_t status;
  311. status = pj_sock_accept(sock_, &newsock, remote_addr, addrlen);
  312. if (status != PJ_SUCCESS)
  313. return Pj_Sock_Stream(-1);
  314. return Pj_Sock_Stream(newsock);
  315. }
  316. //
  317. // shutdown()
  318. //
  319. pj_status_t shutdown(int how = PJ_SHUT_RDWR)
  320. {
  321. return pj_sock_shutdown(sock_, how);
  322. }
  323. };
  324. #endif
  325. //
  326. // Datagram socket.
  327. //
  328. class Pj_Sock_Dgram : public Pj_Socket
  329. {
  330. public:
  331. //
  332. // Default constructor.
  333. //
  334. Pj_Sock_Dgram()
  335. {
  336. }
  337. //
  338. // Initialize from a socket handle.
  339. //
  340. explicit Pj_Sock_Dgram(pj_sock_t sock)
  341. : Pj_Socket(sock)
  342. {
  343. }
  344. //
  345. // Copy constructor.
  346. //
  347. Pj_Sock_Dgram(const Pj_Sock_Dgram &rhs)
  348. : Pj_Socket(rhs)
  349. {
  350. }
  351. //
  352. // Assignment.
  353. //
  354. Pj_Sock_Dgram &operator=(const Pj_Sock_Dgram &rhs)
  355. {
  356. Pj_Socket::operator =(rhs);
  357. return *this;
  358. }
  359. //
  360. // recvfrom()
  361. //
  362. pj_ssize_t recvfrom( void *buf, pj_size_t len, int flag = 0,
  363. Pj_Inet_Addr *fromaddr = NULL)
  364. {
  365. pj_ssize_t bytes = len;
  366. int *addrlen = fromaddr ? &fromaddr->addrlen_ : NULL;
  367. if (pj_sock_recvfrom( sock_, buf, &bytes, flag,
  368. fromaddr, addrlen) != PJ_SUCCESS)
  369. {
  370. return -1;
  371. }
  372. return bytes;
  373. }
  374. //
  375. // sendto()
  376. //
  377. pj_ssize_t sendto( const void *buf, pj_size_t len, int flag,
  378. const Pj_Inet_Addr &addr)
  379. {
  380. pj_ssize_t bytes = len;
  381. if (pj_sock_sendto( sock_, buf, &bytes, flag,
  382. &addr, sizeof(pj_sockaddr_in)) != PJ_SUCCESS)
  383. {
  384. return -1;
  385. }
  386. return bytes;
  387. }
  388. };
  389. #endif /* __PJPP_SOCK_HPP__ */