listen.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. ** JNetLib
  3. ** Copyright (C) 2000-2013 Nullsoft, Inc.
  4. ** Author: Justin Frankel, Ben Allison
  5. ** File: listen.cpp - JNL TCP listen implementation
  6. ** License: see jnetlib.h
  7. */
  8. #include "netinc.h"
  9. #include "util.h"
  10. #include "listen.h"
  11. #include "foundation/error.h"
  12. JNL_Listen::JNL_Listen()
  13. {
  14. m_port=0;
  15. m_socket=-1;
  16. }
  17. int JNL_Listen::Initialize(unsigned short port, sockaddr *which_interface, int family)
  18. {
  19. m_port = port;
  20. char portString[32] = {0};
  21. sprintf(portString, "%d", (int)port);
  22. addrinfo *res;
  23. addrinfo hints;
  24. memset(&hints, 0, sizeof(hints));
  25. hints.ai_family = family;
  26. hints.ai_socktype = SOCK_STREAM;
  27. hints.ai_flags = AI_NUMERICHOST | AI_PASSIVE;
  28. hints.ai_addr = which_interface?which_interface:INADDR_ANY;
  29. if (getaddrinfo(NULL, portString, &hints, &res) == 0)
  30. {
  31. int ret = Initialize(res, 0);
  32. freeaddrinfo(res);
  33. return ret;
  34. }
  35. else
  36. {
  37. return NErr_Error;
  38. }
  39. }
  40. int JNL_Listen::Initialize(addrinfo *address, size_t index)
  41. {
  42. addrinfo *res = address;
  43. while (index--)
  44. {
  45. res = res->ai_next;
  46. if (!res)
  47. return NErr_EndOfEnumeration;
  48. }
  49. m_socket = ::socket(res->ai_family,res->ai_socktype, res->ai_protocol);
  50. if (m_socket < 0)
  51. {
  52. freeaddrinfo(res);
  53. return NErr_Error;
  54. }
  55. else
  56. {
  57. SET_SOCK_BLOCK(m_socket,0);
  58. #ifndef _WIN32
  59. int bflag = 1;
  60. setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, &bflag, sizeof(bflag));
  61. #endif
  62. if (::bind(m_socket, res->ai_addr, (int)res->ai_addrlen))
  63. {
  64. closesocket(m_socket);
  65. m_socket=-1;
  66. return NErr_Error;
  67. }
  68. else if (::listen(m_socket,8)==-1)
  69. {
  70. closesocket(m_socket);
  71. m_socket=-1;
  72. return NErr_Error;
  73. }
  74. }
  75. return NErr_Success;
  76. }
  77. JNL_Listen::~JNL_Listen()
  78. {
  79. if (m_socket>=0)
  80. {
  81. closesocket(m_socket);
  82. }
  83. }
  84. JNL_Connection *JNL_Listen::get_connect(size_t sendbufsize, size_t recvbufsize)
  85. {
  86. if (m_socket < 0)
  87. {
  88. return NULL;
  89. }
  90. sockaddr_storage saddr;
  91. socklen_t length = sizeof(saddr);
  92. SOCKET s = accept(m_socket, (sockaddr *)&saddr, &length);
  93. if (s != -1)
  94. {
  95. JNL_Connection *c=new JNL_Connection(NULL,sendbufsize, recvbufsize);
  96. c->connect(s, (sockaddr *)&saddr, length);
  97. return c;
  98. }
  99. return NULL;
  100. }
  101. socklen_t JNL_Listen::get_address(sockaddr* address, socklen_t *address_len)
  102. {
  103. return getsockname(m_socket, address, address_len);
  104. }
  105. unsigned short JNL_Listen::get_port()
  106. {
  107. if (!m_port)
  108. {
  109. sockaddr_in address;
  110. socklen_t namelen = sizeof(address);
  111. if (getsockname(m_socket, (sockaddr *)&address, &namelen) == 0)
  112. m_port = ntohs(address.sin_port);
  113. }
  114. return m_port;
  115. }