ServerSocket.cpp
上传用户:market2
上传日期:2018-11-18
资源大小:18786k
文件大小:4k
源码类别:

外挂编程

开发平台:

Windows_Unix

  1. /*
  2.  *  OpenKore C++ Standard Library
  3.  *  Copyright (C) 2006,2007  VCL
  4.  *
  5.  *  This library is free software; you can redistribute it and/or
  6.  *  modify it under the terms of the GNU Lesser General Public
  7.  *  License as published by the Free Software Foundation; either
  8.  *  version 2.1 of the License, or (at your option) any later version.
  9.  *
  10.  *  This library 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 GNU
  13.  *  Lesser General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU Lesser General Public
  16.  *  License along with this library; if not, write to the Free Software
  17.  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  18.  *  MA  02110-1301  USA
  19.  */
  20. // Do not compile this file independently, it's supposed to be automatically
  21. // included by another source file.
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include <assert.h>
  25. #include "Socket.h"
  26. #define DEFAULT_BACKLOG_SIZE 5
  27. /**
  28.  * @internal
  29.  * An internal class which implements ServerSocket on Windows.
  30.  */
  31. class WinServerSocket: public ServerSocket {
  32. private:
  33. /** The server socket. */
  34. SOCKET fd;
  35. /**
  36.  * The server socket's port.
  37.  * @invariant port > 0
  38.  */
  39. unsigned short port;
  40. public:
  41. WinServerSocket(const char *address, unsigned short port) {
  42. fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  43. if (fd == INVALID_SOCKET) {
  44. char message[100];
  45. int error = WSAGetLastError();
  46. snprintf(message, sizeof(message),
  47. "Cannot create socket. (error %d)",
  48. error);
  49. throw SocketException(message, error);
  50. }
  51. struct sockaddr_in addr;
  52. char *c_address = NULL;
  53. addr.sin_family = AF_INET;
  54. if (address == NULL) {
  55. addr.sin_addr.s_addr = htonl(INADDR_ANY);
  56. } else {
  57. c_address = strdup(address);
  58. addr.sin_addr.s_addr = inet_addr(c_address);
  59. }
  60. addr.sin_port = htons(port);
  61. if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) == SOCKET_ERROR) {
  62. char message[100];
  63. int error = WSAGetLastError();
  64. snprintf(message, sizeof(message),
  65. "Cannot bind to %s (error %d)",
  66. address, error);
  67. closesocket(fd);
  68. throw SocketException(message, error);
  69. }
  70. if (c_address != NULL) {
  71. free(c_address);
  72. }
  73. if (port == 0) {
  74. int len = sizeof(addr);
  75. if (getsockname(fd, (struct sockaddr *) &addr, &len) == SOCKET_ERROR) {
  76. int error = WSAGetLastError();
  77. closesocket(fd);
  78. throw SocketException("Cannot determine server socket port.", error);
  79. }
  80. this->port = ntohs(addr.sin_port);
  81. } else {
  82. this->port = port;
  83. }
  84. if (listen(fd, DEFAULT_BACKLOG_SIZE) == SOCKET_ERROR) {
  85. char message[100];
  86. int error = WSAGetLastError();
  87. snprintf(message, sizeof(message),
  88. "Cannot listen for connections on socket. (error %d)",
  89. error);
  90. closesocket(fd);
  91. throw SocketException(message, error);
  92. }
  93. }
  94. ~WinServerSocket() {
  95. close();
  96. }
  97. virtual Socket *accept(int timeout) {
  98. assert(timeout >= -1);
  99. if (fd == INVALID_SOCKET) {
  100. throw IOException("Server socket is closed.");
  101. }
  102. if (timeout > -1) {
  103. fd_set readfds;
  104. int result;
  105. struct timeval tv;
  106. tv.tv_sec = 0;
  107. tv.tv_usec = timeout * 1000;
  108. FD_ZERO(&readfds);
  109. FD_SET(fd, &readfds);
  110. result = select(0, &readfds, NULL, NULL, &tv);
  111. if (result == 0) {
  112. return NULL;
  113. } else if (result == SOCKET_ERROR) {
  114. int error = WSAGetLastError();
  115. char message[100];
  116. snprintf(message, sizeof(message),
  117. "Cannot poll socket. (error %d)",
  118. error);
  119. throw IOException(message, error);
  120. }
  121. }
  122. struct sockaddr_in addr;
  123. int len = sizeof(addr);
  124. SOCKET clientfd = ::accept(fd, (struct sockaddr *) &addr, &len);
  125. if (clientfd == INVALID_SOCKET) {
  126. int error = WSAGetLastError();
  127. char message[100];
  128. snprintf(message, sizeof(message),
  129. "Cannot accept client socket. (error %d)",
  130. error);
  131. throw IOException(message, error);
  132. }
  133. return new WinSocket(clientfd);
  134. }
  135. virtual void close() {
  136. if (fd != INVALID_SOCKET) {
  137. closesocket(fd);
  138. fd = INVALID_SOCKET;
  139. }
  140. }
  141. virtual unsigned short getPort() {
  142. return port;
  143. }
  144. virtual bool isClosed() {
  145. return fd == INVALID_SOCKET;
  146. }
  147. };