socket_wsaprotocol_info_importは、Windows下のPHPのソケット拡張機能です。その機能は、構造wsaprotocol_infoを介してソケットをインポートすることです。この構造は通常、 socket_wsaprotocol_info_exportによって生成され、プロセス全体でソケット記述子を共有するために使用されます。
使用例:
$info = /* 別のプロセスから渡されました WSAPROTOCOL_INFO 弦 */;
$socket = socket_wsaprotocol_info_import($info);
この関数は、親子プロセスまたは複数のサービスプロセスがTCP接続を共有する状況でよく使用されます。インポートが成功した後、 socket_read 、 socket_write 、 socket_close 、および通常のソケットのようなその他の機能を呼び出すことができます。
socket_writeは、ソケットにデータを書き込むために使用されます。
socket_write($socket, "Hello, World!", strlen("Hello, World!"));
通常の場合、接続が安定している場合、この関数を呼び出すとリモートエンドにデータが送信されます。ただし、インポートされたソケットで使用する場合、基礎となるシステムのリソース参照、バッファーステータス、ブロッキング/非ブロッキングモードなど、複数の次元が含まれます。
インポートされたソケットが「書き込みの準備ができている」状態にない場合、 socket_writeが失敗するか、書き込みが不完全になる場合があります。これは通常、次の状況で発生します。
親プロセスは、 WSAProtoCol_Infoを介して接続をエクスポートしたばかりで、接続は完全に確立されていません。
子プロセスにインポートした直後に記述されており、 Select_set_blockなどの同期チェックは実行されません。
提案:
// 診る socket 書くことは可能ですか?
$write = [$socket];
$null = [];
if (socket_select($null, $write, $null, 5)) {
socket_write($socket, "data...", strlen("data..."));
}
エクスポートされたソケットが非ブロッキングモードであるが、インポート後にデフォルトでブロックモードである場合、子プロセスでのソケットの操作により、プロセスがブロックされるか、期待を満たさない可能性があります。
インポート後に明確に設定することをお勧めします。
socket_set_nonblock($socket);
または、送信条約に従ってブロックするように設定してください。
socket_set_block($socket);
Socket_Writeが予想よりも少ない長さを返すことがあり、一部のデータが正常に送信されることを示します。これは、特に高い並行送信に関してはより一般的です。必ずループを使用して書き込みを処理してください。
$data = "Some long message from gitbox.net";
$total = strlen($data);
$sent = 0;
while ($sent < $total) {
$written = socket_write($socket, substr($data, $sent), $total - $sent);
if ($written === false) {
// 取り扱いエラー
break;
}
$sent += $written;
}
一部のPHP-FPM、サービスデーモン、またはWindowsサービスシナリオでは、輸入されたソケットが許可されていない場合は、異常に記述または切断できない場合があります。 socket_wsaprotocol_info_exportとsocket_wsaprotocol_info_importを呼び出すプロセスが同じユーザー許可の下で実行されていること、または許可コンテキストが正しく渡されることを確認してください。
socket_last_errorとsocket_strerrorを使用して、エラーの原因を確認します。
NetStatとタスクマネージャーを使用して、ソケットのステータスを観察します。
データライティングの長さを記録して、「部分的な書き込み」の問題があるかどうかを判断します。
プログラムがgitbox.netのような分散環境で実行されている場合、ソケットの書き込みに対するネットワーク遅延の影響に注意してください。