PageRenderTime 28ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/MAIN/nil/src/tcp_socket.cpp

#
C++ | 203 lines | 126 code | 42 blank | 35 comment | 41 complexity | 06915dc380a2e2160403fb36999846bd MD5 | raw file
Possible License(s): AGPL-1.0, GPL-3.0
  1. /***************************************************************************
  2. tcp_socket.cpp - TCP socket handling
  3. --------------------------------------------------------------------------
  4. begin : 1999-11-17
  5. by : Flemming Frandsen
  6. email : dion@swamp.dk
  7. last changed : 2004-01-25
  8. by : Christoph Brill
  9. email : egore@gmx.de
  10. copyright : (C) 1999 by Flemming Frandsen
  11. email : dion@swamp.dk
  12. ***************************************************************************/
  13. #include "tcp_socket.h"
  14. #include "fluff.h"
  15. #include "systemheaders.h"
  16. int recv_timeout(int s, void *buf, int len, unsigned int timeout)
  17. {
  18. int bytes_left = len;
  19. int bytes_done = 0;
  20. unsigned int start_time = time_ms();
  21. while (1) {
  22. int recv_result = recv(s,((char*)buf)+bytes_done,bytes_left,0);
  23. if (recv_result < 0) {
  24. logmsg(lt_error,"recv(%i,((char*)%x)+%i,%i,0); returned %i (%s)",s,(int)buf,bytes_done,bytes_left,errno,strerror(errno));
  25. return -2; //uh, it went bad.
  26. } else if (recv_result > 0) {
  27. bytes_done += recv_result;
  28. bytes_left -= recv_result;
  29. //If this was the last bit of data, return immediatly.
  30. if (bytes_left == 0) return 0;
  31. //reset the timer once we get a bit of data.
  32. start_time = time_ms();
  33. }
  34. //see if we have timed out
  35. if (time_elapsed(start_time,time_ms()) > timeout) return -1;
  36. }
  37. return 0;
  38. }
  39. int send_timeout(int s, void *buf, int len, unsigned int timeout)
  40. {
  41. int bytes_left = len;
  42. int bytes_done = 0;
  43. unsigned int start_time = time_ms();
  44. while (1) {
  45. int send_result = send(s,((char*)buf)+bytes_done,bytes_left,0);
  46. if (send_result < 0) {
  47. logmsg(lt_error,"send(%i,((char*)%x)+%i,%i,0); returned %i (%s)",s,(int)buf,bytes_done,bytes_left,errno,strerror(errno));
  48. return -2; //uh, it went bad.
  49. } else if (send_result > 0) {
  50. bytes_done += send_result;
  51. bytes_left -= send_result;
  52. //If this was the last bit of data, return immediatly.
  53. if (bytes_left == 0) return 0;
  54. //reset the timer once we get a bit of data.
  55. start_time = time_ms();
  56. }
  57. //see if we have timed out
  58. if (time_elapsed(start_time,time_ms()) > timeout) return -1;
  59. }
  60. return 0;
  61. }
  62. //-------------------------------------------------------------------------
  63. int Tcp_socket::send(void *buf, int len, unsigned int timeout)
  64. {
  65. int result = send_timeout(socket, buf, len, timeout);
  66. if (result == -1)
  67. logmsg(lt_error,"Time out while writing to the socket.");
  68. else if (result == -2)
  69. logmsg(lt_error,"Error while writing to the socket: %i",result);
  70. else if (result < 0)
  71. logmsg(lt_error,"AAARGH!.");
  72. if (result < 0) bedone = true;
  73. return result;
  74. }
  75. //-------------------------------------------------------------------------
  76. int Tcp_socket::recv(void *buf, int len, unsigned int timeout)
  77. {
  78. int result = recv_timeout(socket, buf, len, timeout);
  79. if (result == -1)
  80. logmsg(lt_error,"Time out while reading from the socket.");
  81. else if (result == -2)
  82. logmsg(lt_error,"Error while reading from the socket: %i",result);
  83. else if (result < 0)
  84. logmsg(lt_error,"AAARGH!.");
  85. if (result < 0) bedone = true;
  86. return result;
  87. }
  88. //-------------------------------------------------------------------------
  89. int Tcp_socket::send(Serializer_reader *serializer_reader)
  90. {
  91. int net_length = htonl(serializer_reader->getlength());
  92. int error = send(&net_length,sizeof(net_length));
  93. if (error) return error;
  94. //send the state data itself.
  95. error = send(serializer_reader->getbuffer(),serializer_reader->getlength());
  96. if (error) return error;
  97. return 0;
  98. }
  99. //-------------------------------------------------------------------------
  100. int Tcp_socket::recv(Serializer_writer *serializer_writer, int max_sane_size)
  101. {
  102. int net_length = -1;
  103. int error = recv(&net_length,sizeof(net_length));
  104. if (error) return error;
  105. //check the length of the data for bogosity
  106. int length = ntohl(net_length);
  107. if (length < 0 || length > max_sane_size) {
  108. logmsg(lt_error,"In int Tcp_socket::recv(Serializer_writer) we got a length of %i, this is wrong, expect the world to end.",length);
  109. return -50;
  110. }
  111. //get the data itself
  112. error = recv(serializer_writer->setbuffer(length),length);
  113. if (error) return error;
  114. return 0;
  115. }
  116. //-------------------------------------------------------------------------
  117. int Tcp_socket::send(int value)
  118. {
  119. int net_value = htonl(value);
  120. int error = send(&net_value,sizeof(net_value));
  121. if (error) return error;
  122. return 0;
  123. }
  124. //-------------------------------------------------------------------------
  125. int Tcp_socket::recv(int &value)
  126. {
  127. int net_value = -1;
  128. int error = recv(&net_value,sizeof(net_value));
  129. if (error) return error;
  130. value = ntohl(net_value);
  131. return 0;
  132. }
  133. //-------------------------------------------------------------------------
  134. int Tcp_socket::send(Serializable *object)
  135. {
  136. //get the objects state
  137. reader.clear();
  138. object->serialize(&reader);
  139. return send(&reader);
  140. }
  141. //-------------------------------------------------------------------------
  142. int Tcp_socket::recv(Serializable *object)
  143. {
  144. //get the object state
  145. int error = recv(&writer);
  146. if (error) return error;
  147. object->serialize(&writer);
  148. //check the serializer for error conditions.
  149. if (!writer.empty()) {
  150. logmsg(lt_error,"In Tcp_socket we got too many bytes for the obejct to eat, this is wrong, expect the world to end.");
  151. return -51;
  152. }
  153. if (writer.empty_read()) {
  154. logmsg(lt_error,"In Tcp_socket we got too few bytes for the obejct to eat, this is wrong, expect the world to end.");
  155. return -52;
  156. }
  157. return 0;
  158. }