Bonjour,
je compte faire un server tcp synchrone multi-thread en utilisant boost asio.
J'ai essayer d'adapter l'exemple simple de boost de l'echo server (http://www.boost.org/doc/libs/1_55_0...cho_server.cpp) en utilisant un functor et j'obtiens un comportement bizarre...
Je crée mon functor en l'initialisant avec la socket puis je le passe dans un thread et le detache.
Voici mon code:
Lorsque je lance un client (telnet ou http://www.boost.org/doc/libs/1_55_0...cho_client.cpp) voici l'output:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 // g++ -std=c++11 -lboost_system -pthread blocking_echo_serv.cpp -o echo_serv #include <cstdlib> #include <iostream> #include <thread> #include <utility> #include <boost/asio.hpp> #include <atomic> #include <vector> using boost::asio::ip::tcp; const int max_length = 1024; class Session { public: Session(tcp::socket *sock): iSock(sock), iId(sIds) { sIds++; std::cout << "Session[" << iId << "] created\n"; std::cout << "sIds: " << sIds << std::endl; } ~Session() { delete iSock; std::cout << "Session[" << iId << "] deleted\n"; } tcp::socket *sock(){return iSock;} void operator() (){ std::cout << "Session[" << iId << "] starting\n"; try { for (;;) { char data[max_length]; boost::system::error_code error; size_t length = iSock->read_some(boost::asio::buffer(data), error); if (error == boost::asio::error::eof) break; // Connection closed cleanly by peer. else if (error) throw boost::system::system_error(error); // Some other error. boost::asio::write(*iSock, boost::asio::buffer(data, length)); } } catch (std::exception& e) { std::cerr << "Exception in thread: " << e.what() << "\n"; } std::cout << "Session[" << iId << "] finished\n"; } private: tcp::socket *iSock; int iId; static std::atomic<int> sIds; }; std::atomic<int> Session::sIds{0}; void server(boost::asio::io_service& io_service, unsigned short port) { std::vector<Session *> vSessions{}; tcp::acceptor a(io_service, tcp::endpoint(tcp::v4(), port)); for (;;) { tcp::socket *sock = new tcp::socket(io_service); a.accept(*sock); Session *session = new Session(sock); vSessions.push_back(session); std::thread t(*session); t.detach(); std::cout << "Thread detached\n"; } } int main(int argc, char* argv[]) { if (argc != 2) { std::cerr << "Usage: echo_serv <port>\n"; return 1; } try { boost::asio::io_service io_service; server(io_service, std::atoi(argv[1])); } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; } return 0; }
Les premières lignes sont le resultat d'un telnet, la dernière avec l'exception est quand j'en relance un deuxième.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 $ ./echo_serv 1111 Session[0] created sIds: 1 Session[0] starting Session[0] deleted Thread detached Exception in thread: Socket operation on non-socket Session[0] finished Session[0] deleted Exception: accept: Already open
Je ne comprends pas pourquoi mon Functor est supprimer avant/durant l'exécution dans le thread. Je ne comprends pas non plus pourquoi il est supprimé aussi à la fin.
Comment puis je faire pour initialiser un objet et ensuite lancer une de ses functions dans un thread? Ce n'est pas comme cela en utilisant un Functor?
Partager