server.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #ifndef __MAUDIT_SERVER_H
  2. #define __MAUDIT_SERVER_H
  3. #include <stdexcept>
  4. #include <string>
  5. #include <vector>
  6. #include <string.h>
  7. #include <unistd.h>
  8. #include "network.h"
  9. #include "lz77.h"
  10. namespace maudit {
  11. struct client_socket {
  12. private:
  13. static const size_t buffsize = 1<<16;
  14. typedef std::vector<unsigned char> buff_t;
  15. buff_t buff;
  16. buff_t::const_iterator buffi;
  17. buff_t::const_iterator buffe;
  18. lz77::compress_t compressor;
  19. bool compression;
  20. public:
  21. int fd;
  22. ~client_socket() {
  23. if (fd >= 0) {
  24. ::shutdown(fd, SHUT_RDWR);
  25. ::CLOSE(fd);
  26. }
  27. }
  28. client_socket(int _fd) : compressor(lz77::DEFAULT_SEARCHLEN, 8192), compression(false), fd(_fd) {
  29. buff.resize(buffsize);
  30. buffi = buff.end();
  31. buffe = buff.end();
  32. }
  33. void set_compression(bool c) {
  34. compression = c;
  35. }
  36. bool write_(const std::string& s) {
  37. ssize_t tmp = ::send(fd, s.data(), s.size(), MSG_NOSIGNAL);
  38. if (tmp < 0 || tmp != (ssize_t)s.size()) {
  39. return false;
  40. }
  41. return true;
  42. }
  43. bool write(const std::string& s) {
  44. if (compression) {
  45. std::string data = compressor.feed(s);
  46. return write_(data);
  47. } else {
  48. return write_(s);
  49. }
  50. }
  51. bool read(unsigned char& c) {
  52. if (buffi == buffe) {
  53. ssize_t tmp = 0;
  54. tmp = ::recv(fd, RECV_TYPE_CAST &(buff[0]), buffsize, 0);
  55. if (tmp < 0) {
  56. return false;
  57. }
  58. if (tmp == 0) {
  59. return false;
  60. }
  61. buffi = buff.begin();
  62. buffe = buff.begin() + tmp;
  63. }
  64. c = *buffi;
  65. ++buffi;
  66. return true;
  67. }
  68. unsigned int peer_ip() {
  69. struct sockaddr_in address;
  70. SOCKLEN_T address_len = sizeof(address);
  71. int r = ::getpeername(fd, (struct sockaddr*)&address, &address_len);
  72. if (r == 0) {
  73. return address.sin_addr.s_addr;
  74. }
  75. return 0;
  76. }
  77. };
  78. struct server_socket {
  79. private:
  80. void teardown(const std::string& msg) {
  81. ::shutdown(fd, SHUT_RDWR);
  82. ::CLOSE(fd);
  83. fd = -1;
  84. throw std::runtime_error(msg);
  85. }
  86. public:
  87. int fd;
  88. ~server_socket() {
  89. if (fd >= 0) {
  90. ::shutdown(fd, SHUT_RDWR);
  91. ::CLOSE(fd);
  92. }
  93. NETWORK_STOP();
  94. }
  95. server_socket(unsigned int port) : fd(-1) {
  96. NETWORK_INIT();
  97. fd = ::socket(AF_INET, SOCK_STREAM, 0);
  98. if (fd < 0) {
  99. throw std::runtime_error("could not socket()");
  100. }
  101. int is_true = 1;
  102. if (::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, SETSOCKOPT_TYPE_CAST &is_true, sizeof(is_true)) < 0)
  103. teardown("could not setsockopt(SO_REUSEADDR) : ");
  104. if (::setsockopt(fd, SOL_TCP, TCP_NODELAY, SETSOCKOPT_TYPE_CAST &is_true, sizeof(is_true)) < 0)
  105. teardown("could not setsockopt(TCP_NODELAY) : ");
  106. struct sockaddr_in addr;
  107. ::memset(&addr, 0, sizeof(addr));
  108. addr.sin_family = AF_INET;
  109. addr.sin_port = htons(port);
  110. addr.sin_addr.s_addr = 0;
  111. //if (::inet_pton(AF_INET, host.c_str(), (void*)&addr.sin_addr) <= 0)
  112. // teardown("could not inet_pton() : ");
  113. if (::bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0)
  114. teardown("could not bind() : ");
  115. if (::listen(fd, 1024) < 0)
  116. teardown("could not listen() : ");
  117. }
  118. int accept() {
  119. int client = ::accept(fd, NULL, NULL);
  120. if (client < 0) {
  121. throw std::runtime_error("could not accept()");
  122. }
  123. return client;
  124. }
  125. };
  126. }
  127. #endif