Форум программистов, компьютерный форум 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, j, k, razm; double max;
C++ Book Подскажите пожалуйста книгу по чистому С без объектов и прочего, страниц на 200, что бы легко читалось и было информативно. http://www.cyberforum.ru/cpp/thread271948.html
Что такое инстанцирование? C++
class A { ... }; A a; // Это уже инстанцирование A?
Специализация шаблонного класа C++
Каким образом можно написать специализацию шаблонного класса так, чтобы часть методов являлась специализированной, то есть писалась заново, а остальные методы - такие, какими бы они были если бы шаблонный клас был без специализации. template <int Size> class MyClass { public: int Method1(); int Method2(); }; template <>
C++ Книга по C++, которую нельзя найти в интернете http://www.cyberforum.ru/cpp/thread271389.html
мой друг поехал в москву , хочу его попрасить купить мне там книгу по с++ только такую,которую можно найти только на продаже т.е. каторая не имеет доступа на скачивание в инете.кто знает,посоветуйте буду очень благодарен.
C++ Наследование в С++. Создать класс CFile, инкапсулирующий в себе такие функции работы с файлами, как Open, Close, Seek, Read, Write, GetPosition и GetLength. На базе этого класса создать производный класс CMyDataFile – файл, содержащий в себе данные некоторого определенного типа MyData, а также заголовок, облегчающий доступ к этому файлу. Написать программу, демонстрирующую работу с этим классом. Программа должна... подробнее

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

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

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

всем привет.

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

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

Размер: 3.8 Кб

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

Размер: 4.1 Кб

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

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

Размер: 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/15c1e7...1eebe7e08564a7

сервер:
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/0a8e2c...31f28c46ddf9e2

общий хидер:
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/9f9e4f...d44f5074181215

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

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