Alışılmadık bir sorun yaşıyorum. Bir C++ Boost.ASIO web sunucusu var ve bu kodu kullanıyorum gelen istekleri işlemek için:C++ Boost.ASIO async_read_until
boost::asio::async_read_until(
socket_,
response_,
"\r\n\r\n",
boost::bind(
&connection::handle_read_headers,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);
("socket_" Benim boost :: asio :: ip :: tcp :: soket olduğu ve "response_" is bir boost :: asio :: streambuf)
Sadece istek başlıklarını yakalamaya çalışıyorum, daha sonra transfer edilen "İçerik Uzunluğu" ile transfer_exactly eşleştirerek ikinci bir async_read_until işlemi yapıyorum. istek başlığı. Sorun, yukarıdaki kodun çok modern bir sunucuya geri dönmesi için 100-900ms almasıdır (Bu okuma bloğundan, handle_read_headers() çağrılana kadar).
POST /load HTTP/1.1
host: www.mysite.com
Accept: */*
Accept-Encoding: gzip,deflate
Content-type: application/x-www-form-urlencoded
From: googlebot(at)googlebot.com
Origin: http://www.mysite.com
Referer: http://www.mysite.com/another-page/
User-Agent: Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
X-Forwarded-For: 66.249.75.103
X-Forwarded-Port: 80
X-Forwarded-Proto: http
Content-Length: 287
Connection: keep-alive
and-the-actual-content-is-here.... (287 bytes worth)
başlıkları bir \ r \ n \ r \ n ile sona gibi görünüyor ve yüzden değil (EOF'a tüm yol okumadan önce) (function handle_read_headers tetikleyebilir yapar: Gelen istek benziyor tüm sayfayı okurken) - aslında regex'i tetikliyor. Ve bu istekler Google'dan geliyor, bu yüzden onların sonlarında gecikme olmadığından eminim.
Geri dönmek için neden bu kadar uzun sürdüğüne baktığım bir şey var mı? Aync_read_until ile başka yakalar kaçırmış olabilirim?
Teşekkürler!
DÜZENLEME/GÜNCELLEME: Tamam, şimdi kafam çok kafam karıştı. Megabyte'ın önerisini denerken, streambuf'tan bir karakter dizisine geçtim (şans yok), daha sonra async_read_until yerine async_read_some kullanmak için kodumu yeniden düzenledim ve sadece sınırlandırılmış el ile taramaya başladım. Ayrıca tüm OS değişkenlerini (sysctrl.conf) kemik stoğu varsayılanına (olasılıkları daraltmak için) sıfırlarım. response_ şimdi
socket_.async_read_some(
boost::asio::buffer(response_),
boost::bind(
&connection::handle_read,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);
geçerli:: Maalesef hala aynı gelen POST isteği ile) (handle_read çağırarak aşağıdaki kodda 100-900ms gecikmeler görüyorum boşuna için
boost::array<char, 4096> response_;
(aynı 100-900ms gecikmeler). Bunun normal bir yolu yok - herhangi bir düşünce?
EDIT2: Rhashimoto önerisi Başına , ben işleyici izlemeyi etkinleştirdikten ve günlüğünde bu gariplik bulundu: async_accept ve async_receive arasında 700 milisaniye boyunca var
[2013-07-05 15:58:39 - Thread 7fae57e3f700]: Incoming connection (0ms elapsed)
@asio|1373054319.874916|506*508|[email protected]_receive
@asio|1373054319.874963|506*509|[email protected]_accept
@asio|1373054319.875008|<506|
@asio|1373054320.609088|>508|ec=system:0,bytes_transferred=512
@asio|1373054320.609233|508*510|[email protected]_receive
@asio|1373054320.609264|<508|
@asio|1373054320.609284|>510|ec=system:0,bytes_transferred=404
[2013-07-05 15:58:40 - Thread 7fae57e3f700]: Received packet headers (638 bytes) - 734ms elapsed
. kodunda, o (http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/examples/cpp03_examples.html ait "HTTP Sunucusu 2" neredeyse düz - server.cpp ve connection.cpp) Bu bloğun gider: için
new_connection_->start();
new_connection_.reset(new connection(
io_service_pool_.get_io_service()
));
acceptor_.async_accept(
new_connection_->socket(),
boost::bind(
&server::handle_accept,
this,
boost::asio::placeholders::error
)
);
ve baştan():
void connection::start()
{
boost::asio::async_read_until(
socket_,
response_,
"\r\n\r\n",
boost::bind(
&connection::handle_read_headers,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);
}
ve handle_read_headers() çağrıldığında, 700 msn geçmiştir.
Herhangi bir fikri olan var mı? Tamamen kayboldum.
Çok teşekkürler!
Aslında bunun soket nesnesinin bir şekilde meşgul olmasından kaynaklanabileceğini merak ediyorum (veya aşırı yüklenmiş). İşletim sistemi içinde değil, belki de programımdaki başka bir şeyin ortasında olabilir ... bu mümkün mü? Ve bu async_read_until üzerinde bir gecikme neden olabilir mi? – Harry
Ve Keep-Alive bağlantıları ile yoğun bir şekilde çalışıyorum - her istekten sonra bir soket kapatma yapmamalı mıyım (yoksa normal mi)? – Harry
Her şeyden önce, bir performans uzmanı kullanıyor musunuz? Ne diyor? –