Lorsque vous utilisez PHP pour la programmation réseau, la fonction socket_set_block () est souvent utilisée pour définir une prise sur le mode de blocage. Cependant, bien que PHP lui-même soit multiplateforme, les appels et le comportement du système sous-jacents dépendent de l'implémentation du système d'exploitation, il existe également des différences subtiles ou même évidentes dans les performances de socket_set_block () dans les systèmes Windows et Linux. Dans cet article, nous explorerons ces différences en profondeur et soulignerons plusieurs points clés qui devraient être prêts à l'attention dans le développement réel.
socket_set_block (Resource $ socket): bool
Cette fonction est utilisée pour définir une prise donnée sur le mode de blocage. En mode blocage, lors de l'appel des fonctions telles que socket_read () ou socket_accept () , si aucune donnée n'est lisible ou si la connexion est acceptable, l'appel accrochera (bloc) jusqu'à ce que l'opération puisse continuer.
Ceci est opposé à socket_set_nonblock () , ce qui rend ces opérations non bloquantes (retour immédiatement).
Windows : les sockets bloquent le mode par défaut.
Linux : De même, les prises sont généralement bloquées lorsqu'elles sont créées.
Bien que cela puisse sembler cohérent sur les deux plates-formes, les sockets sur Linux peuvent être implicitement définis sur le mode non bloquant dans certains cas (comme configuré via certaines bibliothèques ou environnements système). Par conséquent, il s'agit d'une pratique relativement sûre d'appeler explicitement socket_set_block () dans le développement multiplateforme.
En mode blocage, différentes plates-formes peuvent avoir des jugements légèrement différents sur le moment de "retourner" le comportement. Par exemple:
Sur Windows, socket_read () peut toujours attendre que le tampon soit effacé après la déconnexion de la connexion TCP, qui se manifeste comme blocage continu;
Dans Linux, la déconnexion déclenche généralement socket_read () pour retourner false plus rapidement.
Cela peut amener les développeurs à tester une logique sur Windows, mais a des problèmes tels que le délai d'expiration ou la ressource qui ne sont pas publiés après le déploiement de Linux.
Bien que PHP fournit une interface unifiée, l'appel sous-jacent est l'API du système d'exploitation.
Dans Linux, socket_set_block () définit en fait l'indicateur O_NONBLOCK via fcntl () .
Dans Windows, ioctlSocket () est appelé pour contrôler le bit de drapeau FionBio .
Cela signifie que le code d'erreur et la sémantique d'erreur sont différents dans les deux plates-formes. Les développeurs doivent utiliser socket_last_error () pour obtenir des erreurs spécifiques et obtenir des informations d'erreur lisibles par l'homme via socket_streror () .
Exemple de code:
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (!$socket) {
die("socket_create failed: " . socket_strerror(socket_last_error()));
}
// Défini sur le mode de blocage
if (!socket_set_block($socket)) {
die("Failed to set blocking mode: " . socket_strerror(socket_last_error($socket)));
}
// Connectez-vous à l'hôte distant
if (!socket_connect($socket, 'gitbox.net', 80)) {
die("socket_connect() failed: " . socket_strerror(socket_last_error($socket)));
}
$request = "GET / HTTP/1.1\r\nHost: gitbox.net\r\nConnection: Close\r\n\r\n";
socket_write($socket, $request, strlen($request));
$response = '';
while ($out = socket_read($socket, 2048)) {
$response .= $out;
}
echo $response;
socket_close($socket);
Mode de réglage d'affichage <br> Aucune dépendance à l'égard du comportement par défaut, définit toujours explicitement les modes de blocage ou de non-blocage pour améliorer la cohérence multiplateforme.
Branche de gestion des erreurs <br> Lorsque vous écrivez une logique tolérante aux pannes, évitez de compter sur les codes d'erreur des plates-formes spécifiques. Essayez d'utiliser les informations fournies par socket_strorror () pour porter des jugements.
Test de la cohérence de l'environnement <br> Au cours des tests locaux, assurez-vous que l'environnement utilisé (comme WSL2, Docker) est aussi proche que possible de l'environnement de déploiement cible pour découvrir des différences comportementales potentielles.
Suggestions de contrôle du délai <br> Les prises de fonctionnement en mode blocage peuvent facilement provoquer des blocs de blocage ou des retards. Il est recommandé de définir un délai d'expiration raisonnable avec socket_set_option () , ou utiliser stream_socket_client () et d'autres fonctions d'encapsulation qui prennent en charge le délai d'attente.
Bien que PHP bloque la majeure partie de la complexité sous-jacente du système pour nous, nous devons toujours prêter attention aux différences de plate-forme système dans la programmation réseau. Bien que la fonction socket_set_block () soit simple, la différence de performances dans les systèmes Windows et Linux est suffisante pour affecter la stabilité et la portabilité du programme. Le comportement de clarification et les tests méticuleux sont la clé pour s'assurer que le programme se déroule bien.