2009-04-07 8 views
2

を聞くが、私のコードです:PHP:ソケットはここで問題

<?php 

$host = "127.0.0.1"; 
$portListen = 1234; 
$portSend = 1240; 


// create socket 
$sSender = socket_create(AF_INET, SOCK_STREAM, 0); 

socket_connect($sSender, $host, $portListen); 

socket_write($sSender, "test", strlen ("test")); 


$sListen = socket_create(AF_INET, SOCK_STREAM, 0); 
socket_set_option($sListen, SOL_SOCKET, SO_REUSEADDR, 1); 

socket_bind($sListen, $host, $portSend); 

socket_listen($sListen,1); 
$dataSock = socket_accept($sListen); 
echo socket_read($dataSock, 3, PHP_NORMAL_READ); 

// close sockets 
socket_close($sSender); 
socket_close($sListen); 
?> 

私は別のアプリケーションに "test" を送って、それを受け取り、 "ACK" を返送します。問題は、私はそれを一度しか行うことができないということです。リフレッシュすると、アドレスはすでに使用されているエラーになります。私はphp.netで提案された解決策を試みたが、役に立たなかった。 socket_close()の前にsocket_shutdown()を試行すると接続警告が表示されず、リフレッシュすると終わりのない読み込みができます。

ソケットがすぐに閉じられない理由は、バッファにまだデータがあるためです。しかし、あなたが見ることができるように、私は明示的に1つの接続だけを聞くように述べています。私はアプリケーションから3文字だけを送り、このスクリプトでは3文字を読みます。

私は間違っていますか?

私は2ソケットを使用している理由は、ソケット(ソケット)がすでに接続されているwrite()の後に聞くことができないためです。 write()の後にlisten()をスキップしてread()のためにまっすぐ進むと、無効な引数エラーが返されます。

+0

これを行うもっと簡単な方法が見つかりました。このブログ記事をチェックしてください。 http://www.christophh.net/2012/07/24/php-socket-programming/ –

答えて

2

私は数時間のスリープをしてコードと文書を再分析した後、すべてを修正することができました。あなたは正しいです、1ソケットは確かに十分で正確な方法です:

<?php 

$host = "127.0.0.1"; 
$portListen = 1234; 
$sSender = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket\n"); 

socket_connect($sSender, $host, $portListen) or die("Could not connect\n"); 

socket_write($sSender, "test", strlen ("test")) or die("Could not write output\n"); 

echo socket_read($sSender, 3, PHP_NORMAL_READ); 

socket_close($sSender); 
?> 

とても簡単です!

1

なぜ読み書き用に2つのソケットを作成する必要がありますか?それは奇妙なデザインのように見えます。クライアントアプリケーションは、通常、サーバーとのソケット接続を開き、要求を送信し、サーバーの応答を同じソケットで読み取ります。 また、リスニングソケット(iowサーバー)を作成しても、ファイアウォールやNATゲートウェイを通過することはありません。

yorコメントへの回答:聞く必要はありません。 (サーバーがまだ応答していない場合、操作をブロックする可能性があります)。

+0

私はそれが正しいデザインだと思った。私は最初のソケットでsocket_listenすることはできません...警告:socket_listen()[function.socket-listen]:ソケット[0]でリッスンできません:既に接続されているソケットに対して接続要求が行われました。 C:\ wamp \ www \ sock.phpの22行目 – syaz

1

ソケットが残っているとソケットは残っているので、(クローズ中に)パケットが失われて再送信された場合、そのソケットは開いていないことを示す(リセット)の代わりにきれいな応答になります。これはTCP仕様の一部ですが、これを止めることはできません。

Listen(1)は、接続を1つだけ受け入れることを意味するものではなく、アプリケーションを待っている接続1つ分の待ち行列をaccept()に維持することを意味します。だからあなたが最初のものを受け入れるとすぐに、ソケットはもっと聞く準備ができています。

他のみんなと同じように、なぜ私は奇妙なデザインなのか疑問に思っていますが、あなたの問題を提示し、必ずしもあなたの本当の計画を提示するものではありません。