2011-01-21 19 views
19

localhostのポート80でlistenするlinuxの下でCのソケットAPIを使用してシンプルなサーバを作成しました。今、私はFirefoxから送信するときに1つだけを受信して​​いる間、私は2つの要求を受信するプログラムにブラウザのGoogle Chromeから要求を送信する。サーバソケットはクロムから送信したときに2つのHTTPリクエストを受信し、firefoxから送信するときに受信します

は、私がブラウザで入力したURLは:http://localhost/xyz.html

OUTPUT私はChromeのURLを入力すると

[email protected]:/home/anirudh/workspace/DCMTOL# ./DCMTOL_RUN 

Inside HTTP server Handler 

Inside HTTP request Handler 

**Detected request: clientsocket_fd = 6 clientportnumber = 38027** 

GET /xyz.html HTTP/1.1 

Host: localhost 

Connection: keep-alive 

Cache-Control: max-age=0 

Accept:application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 

User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.224 Safari/534.10 

Accept-Encoding: gzip,deflate,sdch 

Accept-Language: en-US,en;q=0.8 

Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 


Inside HTTP request Handler 

**Detected request: clientsocket_fd = 7 clientportnumber = 38029** 

^C 

[email protected]:/home/anirudh/workspace/DCMTOL# 

私のコードは、read呼び出しで待機して任意のデータを送信しない第2のリクエストだから私はそれを '^ C'で終わらせなければなりません。

OUTPUT私はFIREFOX

[email protected]:/home/anirudh/workspace/DCMTOL# ./DCMTOL_RUN 
Inside HTTP server Handler 
Inside HTTP request Handler 

**Detected request: clientsocket_fd = 6 clientportnumber = 45567** 

GET /xyz.html HTTP/1.1 

Host: localhost 

User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.10 (maverick) Firefox/3.6.13 

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 

Accept-Language: en-us,en;q=0.5 

Accept-Encoding: gzip,deflate 

Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 

Keep-Alive: 115 

Connection: keep-alive 


^C 

[email protected]:/home/anirudh/workspace/DCMTOL# 

問題のURLを入力します。どのように私は一度だけURLを入力すると2つの要求(1が空であることを)送るブラウザをクロムすることができます。上記のように、私は2つの要求を検出しました。私は、クロムからURLを送信する場合にnetstatを実行しようとしましたが、私は両方のリクエストがブラウザによってのみ送信されたことがわかりました。 firefoxからURLを送信すると、上記のように1つのリクエストしか受信されません。ここで

私はクロームからのリクエストを送信する際、事前に

Active Internet connections (w/o servers) 

Proto Recv-Q Send-Q Local Address   Foreign Address   State  PID/Program name 

tcp  0  0 117.195.110.186:48701 74.125.77.102:80  TIME_WAIT - 

tcp  0  0 117.195.110.186:48700 74.125.77.102:80  ESTABLISHED 5699/google-chrome 

tcp  0  0 117.195.110.186:55815 209.85.175.138:80  ESTABLISHED 5699/google-chrome 

tcp  0  0 127.0.0.1:80   127.0.0.1:38029   ESTABLISHED - 

tcp  0  0 127.0.0.1:38029   127.0.0.1:80   ESTABLISHED 5699/google-chrome 

tcp  0  0 127.0.0.1:38027   127.0.0.1:80   ESTABLISHED 5699/google-chrome 

tcp  0  0 127.0.0.1:80   127.0.0.1:38027   ESTABLISHED - 

tcp  0  0 117.195.110.186:35402 74.125.153.125:5222  ESTABLISHED 4430/pidgin 

感謝:)

+2

tcpflowまたはtcpdumpを実行して、要求に実際に何かが送信されているかどうか確認しましたか?それは将来の要求のための接続を開くかもしれません。 (RomanKが述べたように)。 – Kylar

+2

2年後、私はChrome 24で同じ質問を受けました。 – Eye

答えて

46

私のノードサーバーでも同様の問題がありました。 Chromeのfollowing bugが原因です。要約すると、Chromeはすべてのリクエストに対してfaviconのリクエストを送信しています。おそらく、あなたはファビコンを送り返していないので、正当な要求があった後に1つずつリクエストします。

Firefoxと他のほとんどのブラウザは、最初に接続したときにfaviconのリクエストを送信しますが、結果をキャッシュします。すなわち、初めて返されたfaviconがない場合、試し続けます。 Firefoxからのリクエストは1つしか表示されません。 Chromeは残念なことに、faviconの要求に少しでも固執しているようです。

+0

非常に参考、+1 – XORcist

+1

私はfaviconを助けてくれないため、タイムアウト期間のストリームの読み取りをブロックするため、私は空のリクエストに問題がある10秒)。 –

+2

私はそれを見つけました:** 2番目のソケットはfavicon **のためではなく、davidltの答えで説明されているように、そのソケットには何も送られません。 – WKPlus

1

はあなたのサーバーのソースを投稿することができ、ネットのstatの出力でありますか?私の推測では、Chromeは、あなたのサーバーに対してソケットを開いて、同じページへの将来のリクエストを最適化するだけですが、その上でコマンドを送信しません。

+1

そうではありません。私はwiresharkで実際にトレースし、お気に入りのアイコンの別のリクエストを見つけました。 http://stackoverflow.com/a/12795169/986760 – fayyazkl

11

私は現在、Mono/.NET 4.0上に小さな非同期Webサーバーを作成しており、同じことに気づきました。クロムは2つの TCP接続を開きますが、通信には1つのみが使用されます。そのソケットを使用して送信されるデータはありません。ブラウザからウェブページの読み込みを停止しても、Chromeはまだしばらく接続を維持しています。

これはおそらく最適化のためかバグだから@RomanKに同意する必要がありますが、の場合はありませんfaviconその接続がデータ転送されていないためです。

+5

私は最近この現象に遭遇しました。明らかに、新しいリクエストが必要な場合に備えて、すぐにリクエストを行うことができるように、Chromeは「投機的ソケット」を開きます。皮肉なことに、それはページのレンダリングに関してはChromeを遅くするだけのようだ。 – Ruud

+0

空のリクエストにも問題があります。私のサーバーはjavaで書かれており、この要求は受け入れを引き起こし、次のステップはソケットの入力ストリームを読み込みます。残念ながら、タイムアウト(10秒)をブロックします。 : –

+0

この問題でも騙されました。私はpythonでhttpサーバを作成しました。これは、wsgiref/simple_serverをベースにしています。 「データソケットがありません」というメッセージが表示されます。 – WKPlus

0

秒のソケットにデータを送信しません。私たちのNginx Webサーバーログには、400個のエラーが記録されています。この2番目の接続は、data/actual_HTTP_requestをサーバーに送信する前に閉じられているためです。 最初の接続を開き、すぐに2番目の接続を開き、最初の接続を使用して2番目の接続が切断されるまで待ちます。ここで

は、第二の接続について非冗長ダンプです

No.  Time  Source    Destination   Protocol Length Info 
20227 38.688849 89.ZZZ.TTT.208  80.XX.YYY.186   TCP  66  1758 > 80  [SYN] Seq=0 Win=65535 Len=0 MSS=1440 WS=2 SACK_PERM=1 
20228 38.688870 80.XX.YYY.186   89.ZZZ.TTT.208  TCP  66  80 > 1758 [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0 MSS=1460 SACK_PERM=1 WS=128 
20256 38.752121 89.ZZZ.TTT.208  80.XX.YYY.186   TCP  60  1758 > 80 [ACK] Seq=1 Ack=1 Win=65536 Len=0 
26351 50.565758 89.ZZZ.TTT.208  80.XX.YYY.186   TCP  60  1758 > 80 [FIN, ACK] Seq=1 Ack=1 Win=65536 Len=0 
26352 50.565830 80.XX.YYY.186   89.ZZZ.TTT.208  TCP  54  80 > 1758 [FIN, ACK] Seq=1 Ack=2 Win=5888 Len=0 
26396 50.657612 89.ZZZ.TTT.208  80.XX.YYY.186   TCP  60  1758 > 80 [ACK] Seq=2 Ack=2 Win=65536 Len=0 
0

まだファビコン要求のための2番目の接続を開きませんが、クロムは、ファビコンを取得できない場合(私から404を受け取った)ように見えますそれを実際に要求する。バグ(まだ)のように見えます。 'キャッシュ'が間違っていたかもしれません。キャッシュは既に開いていますか?

0

私には、クロムのURLフィールドに書き込み/貼り付けする場合にのみ発生します。アンカータグからは決して起動されません。 リクエストのURLを記録すると、2回送信されたことがわかります。

私は/ usersです。 コード(ノードサーバー)にconsloe.log()を追加して、/ユーザーが2回表示されるのを確認できました。 私はアプリにログインしていないので、私は二重の通知メッセージを受け取るでしょう。

この例では、それを再現することができます

スクリプト1名は:

<?php 

session_start(); 

$_SESSION['x'][] = 'This will show only once'; 
header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=0'); 
header('Location: /to.php'); 

スクリプト2名をredirect.php:あなたは、ペーストをコピーするのであれば

<?php  

session_start(); 

if (isset($_SESSION['x'])) 
    foreach ($_SESSION['x'] as $x) { 
     echo $x . '<br>'; 
} 

unset($_SESSION['x']); 

to.php「SERVERNAME/redirect.php "をURLフィールドに入力すると、結果的にメッセージが2倍になります。

関連する問題