Boost ASIO async_read_some
Je vais avoir des difficultés dans la mise en œuvre d'un simple serveur TCP. Le code suivant est tiré de boost::asio exemples, "Http Server 1" pour être précis.
void connection::start() {
socket_.async_read_some(
boost::asio::buffer(buffer_),
boost::bind(
&connection::handle_read, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);
}
void connection::handle_read(const boost::system::error_code& e, std::size_t bytes_transferred) {
if (!e && bytes_transferred) {
std::cout << " " << bytes_transferred <<"b" << std::endl;
data_.append(buffer_.data(), buffer_.data()+bytes_transferred);
//(1) what here?
socket_.async_read_some(
boost::asio::buffer(buffer_),
boost::bind(
&connection::handle_read, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);
}
else//if (e != boost::asio::error::operation_aborted)
{
std::cout << data_ << std::endl;
connection_manager_.stop(shared_from_this());
}
}
Dans le code d'origine de la buffer_
est assez grand pour garder la totalité de la demande. Ce n'est pas ce dont j'ai besoin. J'ai changé la taille de 32bytes.
Le serveur compile et écoute sur le port 80 de localhost, donc j'essaie de me connecter via mon navigateur web.
Maintenant, si l'énoncé (1) est commenté, seule la première 32bytes de la demande sont lus et la connexion se bloque. Web navigateur conserve l'attente de la réponse, le serveur n'.. je ne sais pas quoi.
Si (1) est retirée, puis l'ensemble de la demande est de lire (et appeded à data_
), mais il ne s'arrête jamais - je annuler la demande dans mon navigateur, et ce n'est qu'à la else { }
le cadre de l'exécution je vois ma demande sur stdout.
Question 1: Comment dois-je gérer une grande demande?
Question 2: Comment dois-je le cache de la demande (actuellement je ajouter de la mémoire tampon à une chaîne de caractères)?
Question 3: Comment puis-je dire que la demande est de plus? En HTTP, il y a toujours une réponse, donc mon navigateur web continue d'attendre pour elle et de ne pas fermer la connexion, mais comment mon serveur savons que la demande est plus (et peut-être de le fermer ou de répondre à certains "200 OK")?
OriginalL'auteur Queequeg | 2012-09-16
Vous devez vous connecter pour publier un commentaire.
Supposons que le navigateur vous envoyer 1360 octets de données, vous dire
asio
pour lire des données dans votre mémoire tampon que vous le dites seulement de 32 octets.alors la première fois que vous appelez votre gestionnaire sera appelé avec 32 octets de début des données. ici, si vous avez des commentaires (1) puis navigateur essayer d'envoyer le reste de ses données(en fait, navigateur déjà envoyé et c'est dans le tampon de l'OS qu'attendez-vous de jeter un regard à partir de là) et vous êtes peut-être bloqué derrière
io_service::run
pour certains miracle!!si vous décommentez (1) comme vous le dites votre boucle commencée, vous avez bien lu premier bloc, puis un autre ... jusqu'à ce que les données que le navigateur a envoyé fini, mais après cela, lorsque vous dites
asio
pour lire des données plus il attendra plus de données que jamais à partir du navigateur( depuis le navigateur déjà envoyé ses informations et est en attente de votre réponse ) et lorsque vous annulez la demande à partir du navigateur, il va fermer son socket et puis votre gestionnaire sera appelé avec une erreur que de dire que je ne peux pas lire plus de données, puisque la connexion est fermée.!!mais ce que vous devez faire ici est: vous devriez en apprendre davantage
HTTP
format et donc de savoir quelles sont les données que votre navigateur a envoyé à vous et à fournir une bonne réponse, et il peut ensuite votre communication avec le client seront pris en compte. dans ce cas, la fin de la mémoire tampon est\r\n\r\n
et quand vous le voyez, vous ne devriez pas lire plus de données, vous devriez processus de ce que vous avez lu jusqu'ici, et ensuite envoyer une réponse au navigateur.en tout cas, je décrivez votre problème, dans n'importe quel protocole vous devez savoir lors de l'écouter et quand parler. dans la situation de l'exemple le navigateur attendre pour votre réponse et vous peut-être attendre un miracle. TCP est un système de transport non d'un protocole( bien sûr c'est un protocole, mais pas pour de vous ou de moi pour ceux qui utilisent les sockets raw ou souhaitez mettre en œuvre le protocole TCP/IP ), et vous devez connaître le format de chaque protocole que vous souhaitez mettre en place et il n'y a pas de solution globale qui fonctionnent avec le protocole
Ok. Ce que sur l'envoi d'un objet sérialisable, comme dans le la Sérialisation exemple. Si j'envoie un objet, puis stimuler la traite automatiquement le contrôle de la taille?
en cas de sérialisation vous avez 2 étapes: d'abord) lire des données à partir de la douille puis) appel boost::serialization désérialiser le tampon. alors d'abord, vous devez savoir quand arrêter de lire. c'est quand je dis, pour chaque protocole, vous devez connaître le format, même pour un protocole personnalisé que vous le concevez pour votre propre usage, je peux vous conseiller un truc simple. dans le côté de l'envoi sérialiser un objet dans un tampon et que vous connaissez la taille de la mémoire tampon puis d'intégrer cette dimension dans le début de l'envoi de la mémoire tampon et recevez côté de lire d'abord la taille et ensuite de lire les données jusqu'à la taille indiquée et désérialiser!! c'est simple
OriginalL'auteur BigBoss