ソケットプログラミングにPHPのsocket_accept()関数を使用する場合、一般的な警告メッセージは次のとおりです。
Warning: socket_accept() expects parameter 1 to be resource, bool given
エラーは次のとおりです。Socket_accept ()関数は、受信したパラメーターがリソースであると予想しますが、実際にはブール値(通常は偽)に渡されます。では、なぜ予想されるソケットリソースの代わりにブールタイプの値が渡されるのでしょうか?根本的な原因は、socket_create()またはsocket_bind()またはsocket_listen()のステップが失敗したことです。
典型的なソケットサーバーコード構造を見てみましょう。
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '0.0.0.0', 8080);
socket_listen($socket);
while (true) {
$client = socket_accept($socket);
// ...クライアント接続を処理します
}
行の1つ( socket_create()など)がfalseを返す場合、 $ socketは有効なソケットリソースではありません。 socket_accept($ socket)を呼び出すときにエラーが発生します:有効なリソースではなく、ブール値(false)が渡されます。
socket_last_error()およびsocket_strerror()関数を使用して、詳細なエラー情報を出力できます。
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
die("socket_create() 失敗: " . socket_strerror(socket_last_error()) . "\n");
}
if (!socket_bind($socket, '0.0.0.0', 8080)) {
die("socket_bind() 失敗: " . socket_strerror(socket_last_error($socket)) . "\n");
}
if (!socket_listen($socket)) {
die("socket_listen() 失敗: " . socket_strerror(socket_last_error($socket)) . "\n");
}
while (true) {
$client = socket_accept($socket);
if ($client === false) {
echo "socket_accept() 失敗: " . socket_strerror(socket_last_error($socket)) . "\n";
continue;
}
$msg = "いらっしゃいませ M66 Socket 仕える!\n";
socket_write($client, $msg, strlen($msg));
socket_close($client);
}
このようにして、どの関数呼び出しが失敗するかを見つける方が簡単で、それにより根本的な問題が修正されます。
許可不十分<br> 80または21など、1024未満のポートにバインドしようとすると、許可が不十分なため失敗します。解決策は、1024を超えるポートを使用するか、管理者の特権でスクリプトを実行することです。
ポートは占有されています<br> ポートが他のプロセスで占有されている場合、 socket_bind()は失敗します。 Netstat -TLNP (Linux)やNetstat -Ano (Windows)などのコマンドを使用して、ポート占有率を表示できます。
違法な拘束先住所<br> 指定されたIPアドレスが違法である場合、またはマシンが構成されていない場合、 socket_bind()は失敗します。 0.0.0.0 (すべてのIPSをバインド)またはマシンの実際のイントラネットIPなど、バウンドアドレスが合法で有効であることを確認してください。
PHPソケット拡張は正しくロードされません<br> PHP.iniでソケット拡張機能が有効になっていることを確認してください。 phpinfo()またはendix_loaded( 'sockets')を介して確認できます。
<?php
$host = '0.0.0.0';
$port = 9000;
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
die("socket_create() 失敗: " . socket_strerror(socket_last_error()) . "\n");
}
if (!socket_bind($socket, $host, $port)) {
die("socket_bind() 失敗: " . socket_strerror(socket_last_error($socket)) . "\n");
}
if (!socket_listen($socket)) {
die("socket_listen() 失敗: " . socket_strerror(socket_last_error($socket)) . "\n");
}
echo "リスニング: $host:$port\n";
while (true) {
$client = socket_accept($socket);
if ($client === false) {
echo "socket_accept() 失敗: " . socket_strerror(socket_last_error($socket)) . "\n";
continue;
}
$welcome = "訪問してください m66.net の Socket 仕える!\n";
socket_write($client, $welcome, strlen($welcome));
socket_close($client);
}
socket_close($socket);
socket_accept()を使用するときに「パラメーター1がリソースになると予想されるエラー」に遭遇した場合、問題はsocket_accept()に直接考えないでください。エラー判断とログ出力を追加することにより、問題をすばやく見つけて、間違ったリンクで時間を無駄にすることを避けることができます。
この記事が、この共通の問題をより明確に理解し、位置決めと解決策を習得するのに役立つことを願っています。