PlaintextConnection.cpp 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #include "common/config.h"
  2. #include <cstring>
  3. #ifndef USE_WINSOCK
  4. # include <netdb.h>
  5. # include <unistd.h>
  6. # include <sys/types.h>
  7. # include <sys/socket.h>
  8. #else
  9. # include <winsock2.h>
  10. # include <ws2tcpip.h>
  11. # undef min
  12. # undef max
  13. #endif // USE_WINSOCK
  14. #include "PlaintextConnection.h"
  15. #ifdef USE_WINSOCK
  16. static void close(int fd)
  17. {
  18. closesocket(fd);
  19. }
  20. #endif // USE_WINSOCK
  21. PlaintextConnection::PlaintextConnection()
  22. : fd(-1)
  23. {
  24. #ifdef USE_WINSOCK
  25. static bool wsaInit = false;
  26. if (!wsaInit)
  27. {
  28. WSADATA data;
  29. WSAStartup(MAKEWORD(2, 2), &data);
  30. }
  31. #endif // USE_WINSOCK
  32. }
  33. PlaintextConnection::~PlaintextConnection()
  34. {
  35. if (fd != -1)
  36. ::close(fd);
  37. }
  38. bool PlaintextConnection::connect(const std::string &hostname, uint16_t port)
  39. {
  40. addrinfo hints;
  41. std::memset(&hints, 0, sizeof(hints));
  42. hints.ai_flags = hints.ai_protocol = 0;
  43. hints.ai_family = AF_UNSPEC;
  44. hints.ai_socktype = SOCK_STREAM;
  45. addrinfo *addrs = nullptr;
  46. std::string portString = std::to_string(port);
  47. getaddrinfo(hostname.c_str(), portString.c_str(), &hints, &addrs);
  48. // Try all addresses returned
  49. bool connected = false;
  50. for (addrinfo *addr = addrs; !connected && addr; addr = addr->ai_next)
  51. {
  52. fd = socket(addr->ai_family, SOCK_STREAM, 0);
  53. connected = ::connect(fd, addr->ai_addr, addr->ai_addrlen) == 0;
  54. if (!connected)
  55. ::close(fd);
  56. }
  57. freeaddrinfo(addrs);
  58. if (!connected)
  59. {
  60. fd = -1;
  61. return false;
  62. }
  63. return true;
  64. }
  65. size_t PlaintextConnection::read(char *buffer, size_t size)
  66. {
  67. ssize_t read = ::recv(fd, buffer, size, 0);
  68. if (read < 0)
  69. read = 0;
  70. return read;
  71. }
  72. size_t PlaintextConnection::write(const char *buffer, size_t size)
  73. {
  74. ssize_t written = ::send(fd, buffer, size, 0);
  75. if (written < 0)
  76. written = 0;
  77. return written;
  78. }
  79. void PlaintextConnection::close()
  80. {
  81. ::close(fd);
  82. fd = -1;
  83. }
  84. int PlaintextConnection::getFd() const
  85. {
  86. return fd;
  87. }