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