Position actuelle: Accueil> Derniers articles> Comment implémenter une communication bidirectionnelle basée sur socket_recvmsg avec la fonction socket_sendmsg?

Comment implémenter une communication bidirectionnelle basée sur socket_recvmsg avec la fonction socket_sendmsg?

M66 2025-07-04

En PHP, la communication bidirectionnelle basée sur les douilles est une tâche de programmation réseau commune. En ce qui concerne la messagerie efficace, les deux fonctions Socket_sendmsg et socket_recvmsg peuvent fournir des fonctions plus avancées pour aider les développeurs à obtenir des modes de communication plus flexibles et complexes. Cet article explorera comment utiliser socket_sendmsg avec socket_recvmsg pour réaliser une communication bidirectionnelle.

1. Introduction à socket_sendmsg et socket_recvmsg

Tout d'abord, nous devons comprendre l'utilisation de base de ces deux fonctions:

  • SOCKET_SENDMSG : Cette fonction est utilisée pour envoyer des données à une prise spécifiée et peut transmettre des indicateurs supplémentaires, des informations de contrôle ou des données d'attachement via l'informatique. La principale différence entre l'informatique et Socket_Send est que Socket_sendmsg offre une flexibilité plus puissante et peut prendre en charge des structures de données plus complexes.

  • socket_recvmsg : cette fonction est utilisée pour recevoir des messages d'une prise. Les messages qu'il peut recevoir non seulement contiennent des données, mais peut également contenir des informations de contrôle, telles que l'adresse de l'expéditeur, les métadonnées de données, etc. Par rapport à Socket_Recv , elles peuvent renvoyer plus d'informations de communication, ce qui rend la communication bidirectionnelle plus flexible.

2. Comment fonctionne la communication bidirectionnelle

Dans les applications pratiques, la communication bidirectionnelle signifie souvent que les deux parties doivent être en mesure d'envoyer et de recevoir des données les unes des autres. Avec socket_sendmsg et socket_recvmsg, nous pouvons y parvenir efficacement. Ces deux fonctions peuvent interagir plus flexiblement en contrôlant l'en-tête de message et la pièce de données.

2.1 Initialiser la connexion de la prise

Tout d'abord, nous devons initialiser une prise, généralement via la fonction socket_create pour créer une prise de type TCP ou UDP. Ensuite, nous pouvons utiliser socket_bind ou socket_connect pour la liaison ou la connexion.

 <span><span><span class="hljs-comment">// créer Socket</span></span><span>
</span><span><span class="hljs-variable">$socket</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_create</span></span><span>(AF_INET, SOCK_STREAM, SOL_TCP);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$socket</span></span><span> === </span><span><span class="hljs-literal">false</span></span><span>) {
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Socket créer失败: "</span></span><span> . </span><span><span class="hljs-title function_ invoke__">socket_strerror</span></span><span>(</span><span><span class="hljs-title function_ invoke__">socket_last_error</span></span><span>());
    </span><span><span class="hljs-keyword">exit</span></span><span>();
}

</span><span><span class="hljs-comment">// Connectez-vous au serveur</span></span><span>
</span><span><span class="hljs-variable">$address</span></span><span> = </span><span><span class="hljs-string">'127.0.0.1'</span></span><span>;
</span><span><span class="hljs-variable">$port</span></span><span> = </span><span><span class="hljs-number">8080</span></span><span>;
</span><span><span class="hljs-variable">$result</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_connect</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, </span><span><span class="hljs-variable">$address</span></span><span>, </span><span><span class="hljs-variable">$port</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$result</span></span><span> === </span><span><span class="hljs-literal">false</span></span><span>) {
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Échec de la connexion: "</span></span><span> . </span><span><span class="hljs-title function_ invoke__">socket_strerror</span></span><span>(</span><span><span class="hljs-title function_ invoke__">socket_last_error</span></span><span>());
    </span><span><span class="hljs-keyword">exit</span></span><span>();
}
</span></span>

2.2 Envoyer des messages à l'aide de socket_sendmsg

La fonction SOCKET_SENDMSG nous permet d'envoyer des messages contenant des structures de données complexes. Habituellement, il résume les données dans une structure MSGHDR qui peut contenir des informations de contrôle supplémentaires. Par exemple, spécifiez le bit de drapeau envoyé, les données supplémentaires, l'adresse de destination, etc.

 <span><span><span class="hljs-variable">$msg</span></span><span> = </span><span><span class="hljs-string">"Hello, Server!"</span></span><span>;
</span><span><span class="hljs-variable">$len</span></span><span> = </span><span><span class="hljs-title function_ invoke__">strlen</span></span><span>(</span><span><span class="hljs-variable">$msg</span></span><span>);

</span><span><span class="hljs-comment">// créer一个消息头</span></span><span>
</span><span><span class="hljs-variable">$msgHdr</span></span><span> = </span><span><span class="hljs-keyword">array</span></span><span>(
    </span><span><span class="hljs-string">'msg_name'</span></span><span> =&gt; </span><span><span class="hljs-literal">null</span></span><span>,           </span><span><span class="hljs-comment">// L&#39;adresse de destination par défaut est vide</span></span><span>
    </span><span><span class="hljs-string">'msg_namelen'</span></span><span> =&gt; </span><span><span class="hljs-number">0</span></span><span>,
    </span><span><span class="hljs-string">'msg_iov'</span></span><span> =&gt; </span><span><span class="hljs-keyword">array</span></span><span>(</span><span><span class="hljs-keyword">array</span></span><span>(</span><span><span class="hljs-string">'iov_base'</span></span><span> =&gt; </span><span><span class="hljs-variable">$msg</span></span><span>, </span><span><span class="hljs-string">'iov_len'</span></span><span> =&gt; </span><span><span class="hljs-variable">$len</span></span><span>)),  </span><span><span class="hljs-comment">// Contenu de données</span></span><span>
    </span><span><span class="hljs-string">'msg_iovlen'</span></span><span> =&gt; </span><span><span class="hljs-number">1</span></span><span>,
    </span><span><span class="hljs-string">'msg_control'</span></span><span> =&gt; </span><span><span class="hljs-literal">null</span></span><span>,
    </span><span><span class="hljs-string">'msg_controllen'</span></span><span> =&gt; </span><span><span class="hljs-number">0</span></span><span>,
    </span><span><span class="hljs-string">'msg_flags'</span></span><span> =&gt; </span><span><span class="hljs-number">0</span></span><span>
);

</span><span><span class="hljs-comment">// Envoyer un message</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">socket_sendmsg</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, </span><span><span class="hljs-variable">$msgHdr</span></span><span>) === </span><span><span class="hljs-literal">false</span></span><span>) {
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Échec de l&#39;envoi: "</span></span><span> . </span><span><span class="hljs-title function_ invoke__">socket_strerror</span></span><span>(</span><span><span class="hljs-title function_ invoke__">socket_last_error</span></span><span>());
    </span><span><span class="hljs-keyword">exit</span></span><span>();
}
</span></span>

2.3 Utilisez socket_recvmsg pour recevoir des messages

La fonction socket_recvmsg est contraire à socket_sendmsg et est utilisée pour recevoir des messages contenant des données complexes de la prise. En plus de la pièce de données, le message qu'il renvoie peut également contenir l'adresse de l'expéditeur, le logo et d'autres informations.

 <span><span><span class="hljs-comment">// Un tampon pour préparer les messages</span></span><span>
</span><span><span class="hljs-variable">$buf</span></span><span> = </span><span><span class="hljs-string">""</span></span><span>;
</span><span><span class="hljs-variable">$bufLen</span></span><span> = </span><span><span class="hljs-number">1024</span></span><span>;
</span><span><span class="hljs-variable">$msgHdrRecv</span></span><span> = </span><span><span class="hljs-keyword">array</span></span><span>(
    </span><span><span class="hljs-string">'msg_name'</span></span><span> =&gt; </span><span><span class="hljs-literal">null</span></span><span>,
    </span><span><span class="hljs-string">'msg_namelen'</span></span><span> =&gt; </span><span><span class="hljs-number">0</span></span><span>,
    </span><span><span class="hljs-string">'msg_iov'</span></span><span> =&gt; </span><span><span class="hljs-keyword">array</span></span><span>(</span><span><span class="hljs-keyword">array</span></span><span>(</span><span><span class="hljs-string">'iov_base'</span></span><span> =&gt; &amp;</span><span><span class="hljs-variable">$buf</span></span><span>, </span><span><span class="hljs-string">'iov_len'</span></span><span> =&gt; </span><span><span class="hljs-variable">$bufLen</span></span><span>)),
    </span><span><span class="hljs-string">'msg_iovlen'</span></span><span> =&gt; </span><span><span class="hljs-number">1</span></span><span>,
    </span><span><span class="hljs-string">'msg_control'</span></span><span> =&gt; </span><span><span class="hljs-literal">null</span></span><span>,
    </span><span><span class="hljs-string">'msg_controllen'</span></span><span> =&gt; </span><span><span class="hljs-number">0</span></span><span>,
    </span><span><span class="hljs-string">'msg_flags'</span></span><span> =&gt; </span><span><span class="hljs-number">0</span></span><span>
);

</span><span><span class="hljs-comment">// Recevoir un message</span></span><span>
</span><span><span class="hljs-variable">$bytesReceived</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_recvmsg</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, </span><span><span class="hljs-variable">$msgHdrRecv</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$bytesReceived</span></span><span> === </span><span><span class="hljs-literal">false</span></span><span>) {
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Recevoir l&#39;échec: "</span></span><span> . </span><span><span class="hljs-title function_ invoke__">socket_strerror</span></span><span>(</span><span><span class="hljs-title function_ invoke__">socket_last_error</span></span><span>());
    </span><span><span class="hljs-keyword">exit</span></span><span>();
}

</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"A reçu un message: "</span></span><span> . </span><span><span class="hljs-variable">$buf</span></span><span> . </span><span><span class="hljs-string">"\n"</span></span><span>;
</span></span>

3. Processus de communication bidirectionnel typique

En usage réel, le processus de base de la communication bidirectionnelle peut être résumé dans les étapes suivantes:

  1. Établissement de connexion : le client se connecte au serveur via socket_connect , et le serveur attend que le client se connecte via socket_accept .

  2. Envoyer un message : le client ou le serveur peut envoyer des messages via socket_sendmsg . Il convient de noter que des données supplémentaires ou des bits d'indicateur peuvent être transmises pour représenter des informations de contrôle spécifiques.

  3. Message de réception : le récepteur reçoit le message via socket_recvmsg . Le message reçu comprend non seulement la partie de données, mais aussi certaines métadonnées (telles que les indicateurs de message, l'expéditeur, etc.).

  4. Envoi et réception alternatifs : le client et le serveur utilisent alternativement socket_sendmsg et socket_recvmsg pour l'échange de données bidirectionnel. Chaque fois que des informations de contrôle différentes ou des structures de données plus complexes peuvent être jointes.

 <span><span><span class="hljs-comment">// Exemple de code côté serveur(Version simplifiée)</span></span><span>
</span><span><span class="hljs-variable">$serverSocket</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_create</span></span><span>(AF_INET, SOCK_STREAM, SOL_TCP);
</span><span><span class="hljs-title function_ invoke__">socket_bind</span></span><span>(</span><span><span class="hljs-variable">$serverSocket</span></span><span>, </span><span><span class="hljs-string">'127.0.0.1'</span></span><span>, </span><span><span class="hljs-number">8080</span></span><span>);
</span><span><span class="hljs-title function_ invoke__">socket_listen</span></span><span>(</span><span><span class="hljs-variable">$serverSocket</span></span><span>);

</span><span><span class="hljs-comment">// En attente de la connexion du client</span></span><span>
</span><span><span class="hljs-variable">$clientSocket</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_accept</span></span><span>(</span><span><span class="hljs-variable">$serverSocket</span></span><span>);

</span><span><span class="hljs-comment">// Recevoir et envoyer des données</span></span><span>
</span><span><span class="hljs-variable">$buffer</span></span><span> = </span><span><span class="hljs-string">''</span></span><span>;
</span><span><span class="hljs-variable">$header</span></span><span> = </span><span><span class="hljs-keyword">array</span></span><span>(
    </span><span><span class="hljs-string">'msg_name'</span></span><span> =&gt; </span><span><span class="hljs-literal">null</span></span><span>,
    </span><span><span class="hljs-string">'msg_namelen'</span></span><span> =&gt; </span><span><span class="hljs-number">0</span></span><span>,
    </span><span><span class="hljs-string">'msg_iov'</span></span><span> =&gt; </span><span><span class="hljs-keyword">array</span></span><span>(</span><span><span class="hljs-keyword">array</span></span><span>(</span><span><span class="hljs-string">'iov_base'</span></span><span> =&gt; &amp;</span><span><span class="hljs-variable">$buffer</span></span><span>, </span><span><span class="hljs-string">'iov_len'</span></span><span> =&gt; </span><span><span class="hljs-number">1024</span></span><span>)),
    </span><span><span class="hljs-string">'msg_iovlen'</span></span><span> =&gt; </span><span><span class="hljs-number">1</span></span><span>,
    </span><span><span class="hljs-string">'msg_control'</span></span><span> =&gt; </span><span><span class="hljs-literal">null</span></span><span>,
    </span><span><span class="hljs-string">'msg_controllen'</span></span><span> =&gt; </span><span><span class="hljs-number">0</span></span><span>,
    </span><span><span class="hljs-string">'msg_flags'</span></span><span> =&gt; </span><span><span class="hljs-number">0</span></span><span>
);
</span><span><span class="hljs-keyword">while</span></span><span> (</span><span><span class="hljs-literal">true</span></span><span>) {
    </span><span><span class="hljs-variable">$bytesReceived</span></span><span> = </span><span><span class="hljs-title function_ invoke__">socket_recvmsg</span></span><span>(</span><span><span class="hljs-variable">$clientSocket</span></span><span>, </span><span><span class="hljs-variable">$header</span></span><span>);
    </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$bytesReceived</span></span><span> === </span><span><span class="hljs-literal">false</span></span><span>) {
        </span><span><span class="hljs-keyword">break</span></span><span>;
    }
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"A reçu un message du client: <span class="hljs-subst">$buffer</span></span></span><span>\n";

    </span><span><span class="hljs-comment">// Envoyer une réponse au client</span></span><span>
    </span><span><span class="hljs-variable">$msg</span></span><span> = </span><span><span class="hljs-string">"Hello from server!"</span></span><span>;
    </span><span><span class="hljs-variable">$msgHdrSend</span></span><span> = </span><span><span class="hljs-keyword">array</span></span><span>(
        </span><span><span class="hljs-string">'msg_name'</span></span><span> =&gt; </span><span><span class="hljs-literal">null</span></span><span>,
        </span><span><span class="hljs-string">'msg_namelen'</span></span><span> =&gt; </span><span><span class="hljs-number">0</span></span><span>,
        </span><span><span class="hljs-string">'msg_iov'</span></span><span> =&gt; </span><span><span class="hljs-keyword">array</span></span><span>(</span><span><span class="hljs-keyword">array</span></span><span>(</span><span><span class="hljs-string">'iov_base'</span></span><span> =&gt; </span><span><span class="hljs-variable">$msg</span></span><span>, </span><span><span class="hljs-string">'iov_len'</span></span><span> =&gt; </span><span><span class="hljs-title function_ invoke__">strlen</span></span><span>(</span><span><span class="hljs-variable">$msg</span></span><span>))),
        </span><span><span class="hljs-string">'msg_iovlen'</span></span><span> =&gt; </span><span><span class="hljs-number">1</span></span><span>,
        </span><span><span class="hljs-string">'msg_control'</span></span><span> =&gt; </span><span><span class="hljs-literal">null</span></span><span>,
        </span><span><span class="hljs-string">'msg_controllen'</span></span><span> =&gt; </span><span><span class="hljs-number">0</span></span><span>,
        </span><span><span class="hljs-string">'msg_flags'</span></span><span> =&gt; </span><span><span class="hljs-number">0</span></span><span>
    );
    </span><span><span class="hljs-title function_ invoke__">socket_sendmsg</span></span><span>(</span><span><span class="hljs-variable">$clientSocket</span></span><span>, </span><span><span class="hljs-variable">$msgHdrSend</span></span><span>);
}
</span></span>

4. Résumé

L'utilisation des fonctions socket_sendmsg et socket_recvmsg peut considérablement améliorer l'efficacité de communication basée sur les douilles, en particulier dans les scénarios où des messages complexes sont requis ou des informations de contrôle supplémentaires sont passées. Leur flexibilité permet aux développeurs de mieux réaliser une communication bidirectionnelle et de terminer l'échange de données par le biais de messages de sondage et de contrôle. Comprendre comment ces fonctions sont utilisées est crucial pour réaliser une communication efficace du réseau.