10
votes

Dans Win32, est-il un moyen de tester si une prise est non bloquante?

dans Win32, est-il un moyen de tester si une prise est non bloquante?

Sous Systèmes POSIX, je ferais quelque chose comme ce qui suit: xxx

Cependant, les sockets Windows ne prennent pas en charge FCNTL (). Le mode non bloquant est Set à l'aide d'IOCTL avec Fionbio, mais il ne semble pas être un moyen de obtenir le mode non bloqué actuel à l'aide d'IOCTL.

Y a-t-il un autre appel sur des fenêtres que je peux utiliser pour déterminer si la prise est actuellement en mode non bloquante?


0 commentaires

3 Réponses :


7
votes

Une réponse légèrement plus longue serait: Non, mais vous saurez généralement s'il est ou non, car il est relativement bien défini.

Toutes les sockets bloquent sauf si vous avez explicitement ioctlsocket () avec Fionbio ou la maintenez sur wsaasyncselect ou wsaeventselect . Ces deux dernières fonctions changent "secrètement" le socket au non-blocage.

Depuis que vous savez si vous avez appelé l'une de ces 3 fonctions, même si vous ne pouvez pas interroger le statut, il est toujours connu. L'exception évidente est que si cette prise provient de certaines bibliothèques tierces dont vous ne savez pas ce que cela fait exactement sur la prise.

Sidenote: Funnyily, une prise peut être bloquée et chevauchée en même temps, ce qui ne semble pas intuitif, mais il a un peu de sens parce qu'ils viennent des paradigmes opposés (état de préparation à la fin de l'achèvement).


1 commentaires

Si j'accepte () une connexion, la nouvelle prise hérite-t-elle l'état non bloquant de la prise d'écoute?



6
votes

précédemment, vous pouvez appeler Wsaisblocking pour déterminer cela. Si vous gérez le code hérité, cela peut toujours être une option.

Sinon, vous pouvez écrire une couche d'abstraction simple sur l'API de prise. Étant donné que toutes les sockets bloquent par défaut, vous pouvez maintenir un drapeau interne et forcer toutes les opérations de la prise via votre API afin que vous sachiez toujours l'état.

Voici un extrait de plate-forme multiplateforme pour définir / obtenir le mode de blocage , bien que cela ne fasse pas exactement ce que vous voulez: xxx


0 commentaires

0
votes

Je suis d'accord avec la réponse acceptée, il n'y a pas de moyen officiel de déterminer l'état de blocage d'une prise sous Windows. Si vous obtenez une prise d'une tierce partie (disons, vous êtes une bibliothèque TLS et vous obtenez la prise de la couche supérieure), vous ne pouvez pas décider s'il s'agit d'un état de blocage ou non.

Malgré cela, je travaille, Solution non officielle et limitée pour le problème qui travaille pour moi pendant une longue période. P>

Je tente de lire 0 octets de la prise. Si c'était une prise de blocage, il retournera 0, au cas où il serait un non-bloquant, il retournera -1 et GetLasterRor équivaut à WSAewouldBlock. P>

int IsBlocking(SOCKET s)
{
    int r = 0;
    unsigned char b[1];
    r = recv(s, b, 0, 0);
    if (r == 0)
        return 1;
    else if (r == -1 && GetLastError() == WSAEWOULDBLOCK)
        return 0;
    return -1; /* In  case it is a connection socket (TCP) and it is not in connected state you will get here 10060 */
}
  • fonctionne avec des sockets UDP li>
  • fonctionne avec des sockets TCP connectés li>
  • ne fonctionne pas avec des sockets TCP non connectés li> ul> p>


0 commentaires