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:
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;
}
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
 
$ ./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
Les premières lignes sont le resultat d'un telnet, la dernière avec l'exception est quand j'en relance un deuxième.

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?