Sto provando a fare amici asio e SSL. Tutto sta andando bene, ma una cosa sta causando disagio: come rilevare se la connessione peer close e distinguerla dalla situazione quando peer basta fare una breve pausa nell'invio dei dati, con l'obiettivo di continuare pochi secondi dopo?boost :: flusso SSL asincrono e asincrono: come rilevare la fine della connessione dati/connessione?
- spinta 1.48
- OpenSSL 1.0.0e
- compilato in codice a 32 bit utilizzando VS10
- Lavorare su W7 x64.
La mia confusione deriva dal fatto che il comportamento di asio è diverso per il socket ordinario e il flusso SSL. Se uso tcp :: socket - ricevo l'errore EOF quando la connessione peer close. Ma per boost :: asio :: ssl :: stream - è non è il caso. Invece, async_read_some restituisce 0 come byte trasferito, e se provo a continuare a leggere da SSL stream - restituisce short_error (http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/overview/core/streams.html).
Quindi, la domanda è: è il comportamento previsto o non si configura nulla?
codiceCliente frammento di:.
class client
{
public:
// bla-bla-bla-bla-bla ....
//
void handle_write(const boost::system::error_code& error)
{
if (!error)
{
socket_.async_read_some(boost::asio::buffer(reply_, max_length),
boost::bind(&client::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else
{
std::cout << "Write failed: " << error.message() << "\n";
}
}
void handle_read(const boost::system::error_code& error,
size_t bytes_transferred)
{
std::cout << "Bytes transfered: " << bytes_transferred << "\n";
if (!error)
{
std::cout << "Reply: ";
std::cout.write(reply_, bytes_transferred);
std::cout << "\n";
std::cout << "Reading...\n";
socket_.async_read_some(boost::asio::buffer(reply_, max_length),
boost::bind(&client::handle_read, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
else if (0 != bytes_transferred)
{
std::cout << "Read failed: " << error.message() << ":"
<< error.value() << "\n";
}
}
private:
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket_;
boost::asio::streambuf request_;
char reply_[max_length];
};
Se togliamo if (! = 0 bytes_transferred), ci arriveremo "breve lettura" :(
Se useremo codice come-ai , output sarà simile a questo:
richiesta è:
GET/HTTP/1.0
Cookie: Nama-nama = Vala-Vala
Bytes trasferito: 1024
Rispondi: HTTP/1.0 200 OK Content-Type: text/html
..... bla -BLA-bla ....
Reading ... Byte trasferiti: 1024
..... bla-bla-bla .... ..... bla-bla-bla ....
Reading ... Byte trasferiti: 482
..... bla-bla-bla ....
Reading ...
byte trasferiti: 0
Allo stesso tempo, se invece async_read_some scriviamo codice, quello che per presa ordinaria restituirà EOF:
boost::asio::async_read(socket_, response_,
boost::asio::transfer_at_least(1),
boost::bind(&client::handle_read_content, this,
boost::asio::placeholders::error));
poi per SSL-socket faremo ottieni 0 come byte trasferiti, quindi short_read.
So che non c'è modo di rilevare la disconnessione nel caso in cui peer, per esempio , fosse appena scollegato dalla rete. Ma come rilevare la disconnessione peer clean esplicita dalla situazione quando il peer non invia dati per un po 'di tempo, ma potrebbe farlo lo un po' più tardi?
Oppure, può essere che non capisco qualcosa?
WBR, Andrey
Alcuni clausola aggiuntiva: SSL/TLS ha la notazione per informare altre parti di chiudere il collegamento. It close_notify alert. Anche il socket TCP sottostante può essere chiuso.
Quindi, fondamentalmente, la mia domanda è: perché, nelle stesse condizioni (il socket TCP è stato chiuso in modo chiaro) ricevo EOF in caso di tcp :: socket, e non ricevo nulla per boost :: asio :: ssl: : flusso.
È una funzionalità di bug o asio?
Ancora un addentum: Per alcuni motivi, asio non mi ha fornito un EOF né se SSL ha ricevuto close_notify né il socket TCP sottostante è stato chiuso.
Sì, sono in grado di rilevare le connessioni morte per timeout. Ma come posso rilevare connessioni SSL correttamente chiuse? Ricevendo short_read?
SSL/TLS ha notazione per informare l'altra parte sulla chiusura della connessione. It close_notify alert. Anche il socket TCP sottostante viene chiuso. Quindi, sostanzialmente, la mia domanda era: perché, nelle stesse condizioni (il socket TCP era chiuso in modo chiaro) ricevo EOF in caso di tcp :: socket, e non ricevo nulla per boost :: asio :: ssl :: stream . È un bug o una funzionalità? – Amdei
Certo, 'close_notify' è per chiusure pulite, che non ti aiuteranno a rilevare quelle cattive. Non so molto su 'boost :: asio :: ssl :: stream', ma suppongo che tu stia facendo operazioni asincrone e la chiusura SSL/TLS causerà problemi con operazioni asincrone (vedi link" Chiusura corretta SSLSocket ") sopra). Potrebbe spiegare un comportamento leggermente diverso. In ogni caso, non importa. Non sarebbe un bug che deve essere corretto, dal momento che non è il modo corretto di scoprire quando interrompere la lettura da uno stream/socket. – Bruno
A proposito, non sono sicuro di cosa intendessi per "* Chiudi alert_notify, anche se il socket TCP sottostante è chiuso. *", Ma un avviso di chiusura TLS non implica che il socket TCP sottostante debba essere chiuso. – Bruno