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
|
void Client::connect( const string & address, int port )
{
askedToHalt_ = false;
boost::thread( boost::bind< int >( boost::ref( *this ), address, port, false ) );
}
void Client::disconnect()
{
askedToHalt_ = true;
threads_.join_all();
}
int Client::operator()( const string & host, int port, bool useWorkaround )
{
askedToHalt_ = false;
if ( useWorkaround )
{
auto_ptr< tcp::socket > pSocket = openSocket( host, port );
SocketBuf in( *pSocket );
SocketBuf out( *pSocket );
istream input( &in );
ostream output( &out );
/*
La classe tcp::socket n'est pas annoncée comme thread-safe si
partagé dans la documentation Boost. Je ne connais cependant
pas assez std::streambuf pour affirmer que ce soit un problème.
+-------------+
| tcp::socket |
+-------------+
^ ^
| |
+-----------+ +-----------+
| SocketBuf | | SocketBuf |
+-----------+ +-----------+
^ ^
| |
+---------+ +---------+
| istream | | ostream |
+---------+ +---------+
thread #1 thread #2
*/
threads_.create_thread( boost::bind< int >( boost::ref( *this ), &input ) );
threads_.create_thread( boost::bind< int >( boost::ref( *this ), &output ) );
threads_.join_all();
pSocket->close();
}
else
{
stringstream portAsString;
portAsString << port;
tcp::iostream inAndOut( host, portAsString.str() );
threads_.create_thread( boost::bind< int >( boost::ref( *this ), static_cast< istream * >( &inAndOut ) ) );
threads_.create_thread( boost::bind< int >( boost::ref( *this ), static_cast< ostream * >( &inAndOut ) ) );
threads_.join_all();
inAndOut.close();
}
return 0;
}
int Client::operator()( istream * in )
{
while ( !askedToHalt_ )
{
enum { bufferSize = 4 };
char buffer[ bufferSize + 1 ];
memset( buffer, 0, bufferSize + 1 );
in->read( buffer, bufferSize ); // Sans le workaround, l'écriture est bloquée durant l'attente en lecture.
canPrintOut_.lock();
cout << "Recu : '" << buffer << "'" << endl;
canPrintOut_.unlock();
}
return 0;
}
int Client::operator()( ostream * out )
{
char c = 'a';
while ( !askedToHalt_ )
{
pause( 2 );
canPrintOut_.lock();
cout << "Envoye : '" << c << "'" << endl;
canPrintOut_.unlock();
*out << c << flush;
if ( ++c > 'z' ) c = 'a';
}
return 0;
} |
Partager