SocketStream.cpp
上传用户:kx_jwh
上传日期:2021-09-03
资源大小:76k
文件大小:5k
源码类别:

STL

开发平台:

Visual C++

  1. /* vim: set tabstop=4 : */
  2. #include "SocketStream.h"
  3. #if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64)
  4. //加入winsock库
  5. typedef int socklen_t;
  6. #pragma comment(lib, "Ws2_32.lib")
  7. #else
  8. # include <sys/stat.h>
  9. # include <fcntl.h>
  10. # include <errno.h>
  11. # include <netdb.h>
  12. # include <sys/types.h>
  13. # include <sys/socket.h>
  14. # include <netinet/in.h>
  15. # include <arpa/inet.h>
  16. # include <unistd.h>
  17. # define closesocket close
  18. #endif
  19. #include <string.h>
  20. #include <string>
  21. #include <sstream>
  22. namespace febird {
  23. SocketException::SocketException(const char* szMsg)
  24.   : IOException(lastError(), szMsg)
  25. {
  26. }
  27. SocketException::SocketException(int errCode, const char* szMsg)
  28.   : IOException(errCode, szMsg)
  29. {
  30. }
  31. int SocketException::lastError()
  32. {
  33. #if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64)
  34. return WSAGetLastError();
  35. #else
  36. return errno;
  37. #endif
  38. }
  39. //////////////////////////////////////////////////////////////////////////
  40. SocketStream::SocketStream(SOCKET socket, bool bAutoClose)
  41. {
  42. this->socket = socket;
  43. posg = 0;
  44. posp = 0;
  45. m_bAutoClose = bAutoClose;
  46. m_bEof = false;
  47. }
  48. SocketStream::~SocketStream(void)
  49. {
  50. if (m_bAutoClose)
  51. ::closesocket(socket);
  52. }
  53. bool SocketStream::waitfor_again()
  54. {
  55. #if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64)
  56. #else
  57. #endif
  58. return false;
  59. }
  60. size_t SocketStream::read(void* data, size_t length)
  61. {
  62. if (m_bEof)
  63. {
  64. throw EndOfFileException("socket graceful closed");
  65. }
  66. int n = ::recv(socket, (char*)data, length, 0);
  67. if (0 == n)
  68. {
  69. m_bEof = true;
  70. throw EndOfFileException("socket graceful closed");
  71. }
  72. if (-1 == n && !waitfor_again())
  73. {
  74. std::ostringstream oss;
  75. oss << "recv packet error, socket=" << socket
  76. << ", want=" << length << ", received=" << n;
  77. ;
  78. throw SocketException(oss.str().c_str());
  79. }
  80. posg += n;
  81. return  n;
  82. }
  83. size_t SocketStream::write(const void* data, size_t length)
  84. {
  85. int  n = ::send(socket, (const char*)data, (int)length, 0);
  86. if (0 == n || -1 == n && !waitfor_again())
  87. {
  88. std::ostringstream oss;
  89. oss << "send packet error, socket=" << socket
  90. << ", want=" << length << ", sent=" << n;
  91. ;
  92. throw SocketException(oss.str().c_str());
  93. }
  94. posp += n;
  95. return  n;
  96. }
  97. //////////////////////////////////////////////////////////////////////////
  98. SocketAcceptor::SocketAcceptor(const char* szBindAddr)
  99. {
  100. const char* colon = strchr(szBindAddr, ':');
  101. std::string strAddr(szBindAddr, colon);
  102. u_short port = atoi(colon + 1);
  103. m_socket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  104. if (-1 == m_socket)
  105. {
  106. perror("error when create socket");
  107. std::string err = "SocketAcceptor::SocketAcceptor(";
  108. err += szBindAddr;
  109. err += ")";
  110. throw SocketException(err.c_str());
  111. }
  112. struct sockaddr_in addr = {0};
  113. addr.sin_family = AF_INET;
  114. addr.sin_addr.s_addr = inet_addr(strAddr.c_str());
  115. addr.sin_port = htons(port);
  116. int err = ::bind(m_socket, (struct sockaddr*)(&addr), sizeof(addr));
  117. if (0 == err) {
  118. printf("bind send to listen socket[%d] at port:%d success!n", m_socket, port);
  119. } else {
  120. std::string errText = IOException::errorText(SocketException::lastError()).c_str();
  121. fprintf(stderr, "SocketConnection::listen, bind tcp socket error: %s", errText.c_str());
  122. ::closesocket(m_socket);
  123. m_socket = -1;
  124. throw SocketException(errText.c_str());
  125. }
  126. err = ::listen(m_socket, 5);
  127. if (0 == err) {
  128. printf("listen successn");
  129. } else {
  130. std::string errText = IOException::errorText(SocketException::lastError()).c_str();
  131. fprintf(stderr, "listen tcp error: %s", errText.c_str());
  132. ::closesocket(m_socket);
  133. m_socket = -1;
  134. throw SocketException(errText.c_str());
  135. }
  136. }
  137. SocketStream* SocketAcceptor::accept()
  138. {
  139. struct sockaddr_in from;
  140. socklen_t size = sizeof(from);
  141. SOCKET client = ::accept(m_socket, (struct sockaddr*)&from, &size);
  142. if (-1 == client)
  143. {
  144. std::string errText = IOException::errorText(SocketException::lastError()).c_str();
  145. fprintf(stderr, "error when accept:%s", errText.c_str());
  146. return 0;
  147. }
  148. SocketStream* stream = new SocketStream(client);
  149. return stream;
  150. }
  151. SocketStream* ConnectSocket(const char* szServerAddr)
  152. {
  153. SOCKET hSocket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  154. if (-1 == hSocket)
  155. return 0;
  156. const char* colon = strchr(szServerAddr, ':');
  157. std::string strAddr(szServerAddr, colon);
  158. u_short port = atoi(colon + 1);
  159. struct sockaddr_in addr = {0};
  160. addr.sin_family = AF_INET;
  161. addr.sin_addr.s_addr = inet_addr(strAddr.c_str());
  162. addr.sin_port = htons(port);
  163. int err = ::connect(hSocket, (sockaddr*)&addr, sizeof(addr));
  164. if (0 == err) {
  165. DEBUG_printf("connect %s successn", szServerAddr);
  166. } else {
  167. std::string errText = IOException::errorText(SocketException::lastError()).c_str();
  168. fprintf(stderr, "error when connect: %s", errText.c_str());
  169. ::closesocket(hSocket);
  170. hSocket = -1;
  171. throw SocketException(errText.c_str());
  172. }
  173. SocketStream* stream = new SocketStream(hSocket);
  174. return stream;
  175. }
  176. } // febird