Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

Баг asio? или баг TCP стека? - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ не могу разобраться с программой на С++. Метод Жордана-Гаусса http://www.cyberforum.ru/cpp/thread272048.html
могу указать в каком месте не понимаю. Очень прошу, дайте коментарии к программе. #include <iostream.h> #include <conio.h> #include <stdlib.h> void main() { int colPos, rowPos; int i,...
C++ Book Подскажите пожалуйста книгу по чистому С без объектов и прочего, страниц на 200, что бы легко читалось и было информативно. http://www.cyberforum.ru/cpp/thread271948.html
Что такое инстанцирование? C++
class A { ... }; A a; // Это уже инстанцирование A?
Специализация шаблонного класа C++
Каким образом можно написать специализацию шаблонного класса так, чтобы часть методов являлась специализированной, то есть писалась заново, а остальные методы - такие, какими бы они были если бы...
C++ Книга по C++, которую нельзя найти в интернете http://www.cyberforum.ru/cpp/thread271389.html
мой друг поехал в москву , хочу его попрасить купить мне там книгу по с++ только такую,которую можно найти только на продаже т.е. каторая не имеет доступа на скачивание в инете.кто знает,посоветуйте...
C++ Наследование в С++. Создать класс CFile, инкапсулирующий в себе такие функции работы с файлами, как Open, Close, Seek, Read, Write, GetPosition и GetLength. На базе этого класса создать производный класс CMyDataFile –... подробнее

Показать сообщение отдельно
niXman
Эксперт С++
3138 / 1450 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2

Баг asio? или баг TCP стека? - C++

08.04.2011, 14:50. Просмотров 9905. Ответов 5
Метки (Все метки)

всем привет.

повстречался с очень странным багом. и не могу определить кто бажит, asio, или TCP-стек.

на стороне клиента, сохраняю отправляемые массивы в файл, чтоб убедится в том, что массивы не портятся.
так и есть. массивы не искаженны:
Название: 1.png
Просмотров: 622

Размер: 3.8 Кб

на стороне сервера, так же, сохраняю принятые массивы.
но тут, массив приходит искаженным:
Название: 2.png
Просмотров: 605

Размер: 4.1 Кб

от снифф этого участка, tcpdump`ом, на стороне клиента:
Баг asio? или баг TCP стека?

а это на стороне сервера:
Название: 4.png
Просмотров: 596

Размер: 3.7 Кб



на стороне клиента, как раз в то место где данные искаженны, добавлены какие-то данные. не мои.
видно, что на стороне сервера, массив, после прочтения при помощи asio, уже испорчен. но tcpdump показывает что массив пришел целым.
я в замешательстве

еще более странно то, что если третьим аргументом клиенту передать "1" - то между асинхронными записями будет использоваться sleep() в 1мс - что полностью решает проблему. но такое решение не подходит.

выложу код в тему, в надежде, что кто-то внесет ясность в ситуацию.

клиент:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include "header.hpp"
 
/***************************************************************************/
 
int main(int argc, char** argv) {
   if ( argc != 4 ) {
      std::cout << "client ip port 0/1 - sleed disabled/enabled" << std::endl;
      return 0;
   }
   std::string ip = argv[1];
   boost::uint16_t port = boost::lexical_cast<boost::uint16_t>(argv[2]);
   bool wsleep = (argv[3][0] == '1');
   std::cout << "sleep " << (wsleep?"enabled":"disabled") << std::endl;
   
   FILE* in = fopen("client_in.log", "wb");
   FILE* out= fopen("client_out.log", "wb");
   if ( !out || !in ) {
      std::cout << "can`t open file!" << std::endl;
      return 1;
   }
 
   boost::asio::ip::tcp::endpoint endpoint(
      boost::asio::ip::address::from_string(ip), port
   );
 
   boost::asio::io_service ios;
   boost::shared_ptr<boost::asio::io_service::work> work(new boost::asio::io_service::work(ios));
 
   boost::thread thread(boost::bind(&boost::asio::io_service::run, &ios));
   
   boost::asio::ip::tcp::socket socket(ios);
   socket.connect(endpoint);
 
   boost::asio::socket_base::non_blocking_io non_blocking_io(true);
   socket.io_control(non_blocking_io);
 
   client_read(socket, in);
 
   for ( size_t idx = 0; idx < 100000000; ++idx ) {
      char* buf = new char[send_buffer_size];
      sprintf(buf, "cs:%8dn", idx);
      start_write(socket, buf, out);
      if ( wsleep ) {
         boost::this_thread::sleep(boost::posix_time::microseconds(1000));
      }
   }
 
   std::cout
   << "send data to server finished!" << std::endl
   << "waiting for all ask`s from server..." << std::endl;
 
   work.reset();
 
   while ( counter ) {
      boost::this_thread::sleep(boost::posix_time::microseconds(1000));
      std::cout << "." << std::flush;
   }
 
   std::cout << std::endl << std::endl
   << "all ask`s received." << std::endl
   << "terminate client..." << std::endl;
 
   socket.cancel();
   socket.close();
 
   thread.join();
   fclose(in);
   fclose(out);
}
 
/***************************************************************************/
http://liveworkspace.org/code/15c1e78ea45184f18f1eebe7e08564a7

сервер:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include "header.hpp"
 
/***************************************************************************/
 
int main(int argc, char** argv) {
   if ( argc != 3 ) {
      std::cout << "server ip port" << std::endl;
      return 0;
   }
   std::string ip = argv[1];
   boost::uint16_t port = boost::lexical_cast<boost::uint16_t>(argv[2]);
 
   FILE* in = fopen("server_in.log", "wb");
   FILE* out= fopen("server_out.log", "wb");
   if ( !out || !in ) {
      std::cout << "can`t open file!" << std::endl;
      return 1;
   }
 
   boost::asio::ip::tcp::endpoint endpoint(
      boost::asio::ip::address::from_string(ip), port
   );
   
   boost::asio::io_service ios;
   boost::asio::ip::tcp::acceptor acceptor(ios, endpoint);
   boost::asio::ip::tcp::socket socket(ios);
 
   acceptor.accept(socket);
   std::cout << "new connection from: " << socket.remote_endpoint().address().to_string() << std::endl;
   
   boost::asio::socket_base::non_blocking_io non_blocking_io(true);
   socket.io_control(non_blocking_io);
 
   server_read(socket, in, out);
 
   ios.run();
 
   fclose(in);
   fclose(out);
}
 
/***************************************************************************/
http://liveworkspace.org/code/0a8e2cb728f85caa5d31f28c46ddf9e2

общий хидер:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#ifndef _header_hpp_included_
#define _header_hpp_included_
 
#include <iostream>
#include <cstdio>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/lexical_cast.hpp>
 
enum { recv_buffer_size = 13 };
enum { send_buffer_size = 13 };
 
volatile size_t counter = 0;
 
/***************************************************************************/
 
void client_readed(
   boost::asio::ip::tcp::socket&,
   char*,
   FILE*,
   const boost::system::error_code&
);
 
void client_read(
   boost::asio::ip::tcp::socket& sock,
   FILE* out
) {
   char* buf = new char[recv_buffer_size];
   boost::asio::async_read(
      sock,
      boost::asio::buffer(buf, recv_buffer_size),
      boost::bind(
         &client_readed,
         boost::ref(sock),
         buf,
         out,
         boost::asio::placeholders::error
      )
   );
}
 
void client_readed(
   boost::asio::ip::tcp::socket& sock,
   char* buf,
   FILE* out,
   const boost::system::error_code& e
) {
   if ( e ) {
      if ( !counter ) return;
      std::cout << "read handler: " << e.message() << std::endl;
      return;
   }
 
   fwrite(buf, recv_buffer_size, 1, out);
 
   counter--;
 
#ifdef _my_debug_
   printf("client_readed(): %s", buf);
   fflush(stdout);
#endif
 
   static size_t idx = 0;
   size_t tmp = 0;
   char* p = strchr(buf, ':');
   if ( p ) {
      p++;
      sscanf(p, "%8d", &tmp);
   } else {
      throw std::runtime_error("input data error!");
   }
   
   delete[] buf;
   
   if ( idx != tmp ) {
      std::ostringstream os;
      os << "read error. expected " << idx << " get " << tmp;
      throw std::runtime_error(os.str());
   }
   idx++;
   client_read(sock, out);
}
 
/***************************************************************************/
 
void writen(
   char*,
   FILE*,
   const boost::system::error_code&
);
 
void start_write(
   boost::asio::ip::tcp::socket& sock,
   char* buf,
   FILE* out
) {
   counter++;
   boost::asio::async_write(
      sock,
      boost::asio::buffer(buf, send_buffer_size),
      boost::bind(
         &writen,
         buf,
         out,
         boost::asio::placeholders::error
      )
   );
}
 
void writen(
   char* buf,
   FILE* out,
   const boost::system::error_code& e
) {
   fwrite(buf, send_buffer_size, 1, out);
   delete[] buf;
   if ( e ) {
      std::cout << "writen(): " << e.message() << std::endl;
   }
}
 
/***************************************************************************/
 
void server_readed(
   boost::asio::ip::tcp::socket&,
   char*,
   FILE*,
   FILE*,
   const boost::system::error_code&
);
   
void server_read(
   boost::asio::ip::tcp::socket& sock,
   FILE* in,
   FILE* out
) {
   char* buf = new char[recv_buffer_size];
   boost::asio::async_read(
      sock,
      boost::asio::buffer(buf, recv_buffer_size),
      boost::bind(
         &server_readed,
         boost::ref(sock),
         buf,
         in,
         out,
         boost::asio::placeholders::error
      )
   );
}
 
void server_readed(
   boost::asio::ip::tcp::socket& sock,
   char* buf,
   FILE* in,
   FILE* out,
   const boost::system::error_code& e
) {
   if ( e ) {
      std::cout << "read handler: " << e.message() << std::endl;
      return;
   }
 
#ifdef _my_debug_
   printf("server_readed(): %s", buf);
#endif
 
   fwrite(buf, recv_buffer_size, 1, in);
   
   static const char* ptr = "sc:";
   memcpy(buf, ptr, strlen(ptr));
   start_write(sock, buf, out);
   server_read(sock, in, out);
}
 
/***************************************************************************/
 
#endif // _header_hpp_included_
http://liveworkspace.org/code/9f9e4f95548699feb5d44f5074181215

всем спасибо.

зы
во вложении, архив с исходниками и Makefile`ом. проверено на gcc-linux и на mingw32.
asiotest2.zip
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru