Socket.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 "Socket.h"
  23. namespace OSL {
  24. namespace _Intern {
  25. static void
  26. initWinSock() {
  27. WORD version;
  28. WSADATA data;
  29. version = MAKEWORD(2, 2);
  30. WSAStartup(version, &data);
  31. }
  32. /**
  33. * @internal
  34. * An internal class which implements WinSocket's input stream.
  35. */
  36. class InStream: public InputStream {
  37. private:
  38. SOCKET fd;
  39. bool closed;
  40. bool m_eof;
  41. public:
  42. InStream(SOCKET fd) {
  43. this->fd = fd;
  44. m_eof = false;
  45. closed = false;
  46. }
  47. virtual void
  48. close() {
  49. if (!closed) {
  50. shutdown(fd, SD_RECEIVE);
  51. closed = true;
  52. }
  53. }
  54. virtual bool
  55. eof() const throw(IOException) {
  56. return m_eof;
  57. }
  58. virtual int
  59. read(char *buffer, unsigned int size) throw(IOException) {
  60. assert(buffer != NULL);
  61. assert(size > 0);
  62. if (m_eof) {
  63. return -1;
  64. }
  65. ssize_t result = ::recv(fd, buffer, size, 0);
  66. if (result == SOCKET_ERROR) {
  67. throw IOException("Unable to receive data.", WSAGetLastError());
  68. } else if (result == 0) {
  69. m_eof = true;
  70. return -1;
  71. } else {
  72. return result;
  73. }
  74. }
  75. };
  76. /**
  77. * @internal
  78. * An internal class which implements WinSocket's output stream.
  79. */
  80. class OutStream: public OutputStream {
  81. private:
  82. SOCKET fd;
  83. bool closed;
  84. public:
  85. OutStream(SOCKET fd) {
  86. this->fd = fd;
  87. closed = false;
  88. }
  89. virtual void
  90. close() {
  91. if (!closed) {
  92. shutdown(fd, SD_RECEIVE);
  93. closed = true;
  94. }
  95. }
  96. virtual void
  97. flush() throw(IOException) {
  98. }
  99. virtual unsigned int
  100. write(const char *data, unsigned int size) throw(IOException) {
  101. assert(data != NULL);
  102. assert(size > 0);
  103. ssize_t result = ::send(fd, data, size, 0);
  104. if (result == SOCKET_ERROR) {
  105. throw IOException("Unable to send data.", WSAGetLastError());
  106. }
  107. return result;
  108. }
  109. };
  110. WinSocket::WinSocket(const char *address, unsigned short port) {
  111. fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  112. if (fd == INVALID_SOCKET) {
  113. char message[100];
  114. int error = WSAGetLastError();
  115. snprintf(message, sizeof(message),
  116. "Cannot create socket. (error %d)",
  117. error);
  118. throw SocketException(message, error);
  119. }
  120. struct hostent *ent;
  121. char *ip;
  122. ent = gethostbyname(address);
  123. if (ent == NULL) {
  124. char message[200];
  125. int error = WSAGetLastError();
  126. snprintf(message, sizeof(message),
  127. "Host %s not found.",
  128. address);
  129. closesocket(fd);
  130. throw HostNotFoundException(message, error);
  131. }
  132. ip = inet_ntoa(*(struct in_addr *)*ent->h_addr_list);
  133. sockaddr_in addr;
  134. addr.sin_family = AF_INET;
  135. addr.sin_port = htons(port);
  136. addr.sin_addr.s_addr = inet_addr(ip);
  137. if (connect(fd, (const struct sockaddr *) &addr, sizeof(addr)) == SOCKET_ERROR) {
  138. char message[300];
  139. int error = WSAGetLastError();
  140. snprintf(message, sizeof(message),
  141. "Cannot connect to %s:%d: error %d",
  142. address, port, error);
  143. closesocket(fd);
  144. throw SocketException(message, error);
  145. }
  146. in = new InStream(fd);
  147. out = new OutStream(fd);
  148. }
  149. WinSocket::WinSocket(SOCKET sock) {
  150. assert(sock != INVALID_SOCKET);
  151. fd = sock;
  152. in = new InStream(fd);
  153. out = new OutStream(fd);
  154. }
  155. WinSocket::~WinSocket() {
  156. in->close();
  157. in->unref();
  158. out->close();
  159. out->unref();
  160. closesocket(fd);
  161. }
  162. InputStream *
  163. WinSocket::getInputStream() const {
  164. return in;
  165. }
  166. OutputStream *
  167. WinSocket::getOutputStream() const {
  168. return out;
  169. }
  170. } // namespace _Intern
  171. } // namespace OSL