Guest User

Untitled

a guest
Nov 20th, 2018
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.83 KB | None | 0 0
  1. #include "tcp.h"
  2.  
  3.  
  4.  
  5.  
  6.  
  7. namespace tcp
  8. {
  9. sock create_socket()
  10. {
  11. return sock( socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) );
  12. }
  13.  
  14. sock create_socket_connect( char *addr, uint16_t port )
  15. {
  16. sockaddr_in name = {0};
  17. SOCKET s;
  18. int r;
  19.  
  20. name.sin_addr.s_addr = inet_addr(addr);
  21. name.sin_family = AF_INET;
  22. name.sin_port = htons(port);
  23.  
  24. s = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
  25. assert( s != SOCKET_ERROR );
  26.  
  27. r = ::connect( s, (sockaddr *)&name, sizeof(name) );
  28. assert( r != SOCKET_ERROR );
  29.  
  30. return sock(s);
  31. }
  32.  
  33.  
  34. sock::sock( SOCKET s )
  35. {
  36. this->s = s;
  37. this->on_recv = nullptr;
  38. }
  39.  
  40. sock::sock()
  41. {
  42. this->s = SOCKET_ERROR;
  43. this->on_recv = nullptr;
  44. }
  45.  
  46. void recv_loop_spawn( sock *s )
  47. {
  48. std::thread( [] (sock sk) {
  49. sk.recv_loop();
  50. }, *s).detach();
  51. }
  52.  
  53. void sock::recv_loop()
  54. {
  55. int r;
  56. char buff[1536];
  57.  
  58. for (;;) {
  59. if ( this->on_recv ) {
  60. r = recv( this->s, buff, sizeof(buff), NULL );
  61.  
  62. if ( r == 0 ) { // close connection
  63. this->on_recv( this, nullptr, r, status::CLOSE );
  64.  
  65. return;
  66. } else if ( r == -1 ) { // error.
  67. this->on_recv( this, nullptr, r, status::FAIL );
  68.  
  69. return;
  70. } else { // data
  71. this->on_recv( this, (uint8_t *)buff, r, status::OK );
  72. }
  73. }
  74. }
  75. }
  76.  
  77. status sock::connect( char *addr, uint16_t port, void (*on_connect)(sock *_this, status st) )
  78. {
  79. sock sk = create_socket_connect( addr, port );;
  80.  
  81. if ( on_connect )
  82. on_connect( &sk, status::OK );
  83.  
  84. recv_loop_spawn(&sk);
  85.  
  86. return status::OK;
  87. }
  88.  
  89. status sock::send( uint8_t *buffer, uint32_t buffer_len, void (*on_sent)(sock *_this, status st) )
  90. {
  91. std::thread( [buffer, buffer_len, on_sent] (sock *__this, SOCKET s) {
  92. int r = ::send( s, (const char *)buffer, buffer_len, NULL );
  93.  
  94. if ( on_sent )
  95. on_sent(__this, r != SOCKET_ERROR ? status::OK : status::FAIL );
  96.  
  97. }, this, this->s).detach();
  98.  
  99. return status::OK;
  100. }
  101.  
  102.  
  103. status server::listen( char *address, uint16_t port, void (*on_accept)(sock *_this, status st) )
  104. {
  105. int r;
  106. SOCKET s;
  107. sockaddr_in name;
  108.  
  109. s = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
  110. assert( s != SOCKET_ERROR );
  111.  
  112. memset( &name, 0, sizeof(name) );
  113. name.sin_addr.s_addr = inet_addr( address );
  114. name.sin_port = htons(port);
  115. name.sin_family = AF_INET;
  116.  
  117. r = bind( s, (sockaddr *)&name, sizeof(name) );
  118. assert( r != SOCKET_ERROR );
  119.  
  120. r = ::listen( s, 64 );
  121. assert( r != SOCKET_ERROR );
  122.  
  123. std::thread( [s, on_accept] () {
  124. int namelen;
  125. sockaddr_in name;
  126. SOCKET con;
  127. sock sk;
  128.  
  129. for (;;) {
  130. namelen = sizeof(name);
  131. con = accept( s, (sockaddr *)&name, &namelen );
  132. assert( con != SOCKET_ERROR );
  133. sk = sock( con );
  134.  
  135. on_accept( &sk, status::OK );
  136.  
  137. recv_loop_spawn(&sk);
  138. }
  139. }).detach();
  140.  
  141. return status::OK;
  142. }
  143. };
Add Comment
Please, Sign In to add comment