Share via


Codici di errore - errno, h_errno e WSAGetLastError

Nelle applicazioni Winsock i codici di errore vengono recuperati usando la funzione WSAGetLastError , i socket di Windows sostituiscono la funzione GetLastError di Windows. I codici di errore restituiti da Windows Sockets sono simili alle costanti del codice di errore del socket UNIX, ma le costanti sono tutte precedute da WSA. Nelle applicazioni Winsock verrà restituito il codice di errore WSAEWOULDBLOCK, mentre nelle applicazioni UNIX verrà restituito il codice di errore EWOULDBLOCK.

I codici di errore impostati da Windows Sockets non vengono resi disponibili tramite la variabile errno . Inoltre, per la classe getXbyY di funzioni, i codici di errore non vengono resi disponibili tramite la variabile h_errno . La funzione WSAGetLastError è progettata per offrire un modo affidabile per un thread in un processo multithreading per ottenere informazioni sull'errore per thread.

Per la compatibilità con Berkeley UNIX (BSD), le versioni iniziali di Windows (Windows 95 con Windows Socket 2 Update e Windows 98, ad esempio) ridefinivano le costanti di errore di Berkeley regolari rilevate in errno.h in BSD come errori WSA di Windows Sockets equivalenti. Ad esempio, ECONNREFUSED è stato definito come WSAECONNREFUSED nel file di intestazione Winsock.h . Nelle versioni successive di Windows (Windows NT 3.1 e versioni successive) queste definizioni sono state impostate come commento per evitare conflitti con errno.h usato con Microsoft C/C++ e Visual Studio.

Il file di intestazione Winsock2.h incluso in Microsoft Windows Software Development Kit (SDK), Platform Software Development Kit (SDK) e Visual Studio contiene ancora un blocco di definizioni commentato all'interno di un blocco di #ifdef 0 e #endif che definiscono i codici di errore del socket BSD come le costanti di errore WSA. Questi possono essere usati per garantire una certa compatibilità con la programmazione socket UNIX, BSD e Linux. Per la compatibilità con BSD, un'applicazione può scegliere di modificare winsock2.h e rimuovere il commento da questo blocco. Tuttavia, gli sviluppatori di applicazioni sono fortemente sconsigliati di rimuovere il commento da questo blocco a causa di inevitabili conflitti con errno.h nella maggior parte delle applicazioni. Inoltre, gli errori del socket BSD vengono definiti in valori molto diversi rispetto a quelli usati nei programmi UNIX, BSD e Linux. Gli sviluppatori di applicazioni sono molto invitati a usare le costanti di errore WSA nelle applicazioni socket.

Queste definizioni rimangono impostate come commento nell'intestazione Winsock2.h all'interno di un blocco #ifdef 0 e #endif. Se uno sviluppatore di applicazioni insiste sull'uso dei codici di errore BSD per la compatibilità, un'applicazione può scegliere di includere una riga del modulo:

#include <windows.h>

#define errno WSAGetLastError()

Ciò consente al codice di rete scritto di usare errno globale per funzionare correttamente in un ambiente a thread singolo. Ci sono alcuni svantaggi molto gravi. Se un file di origine include codice che controlla errno per le funzioni socket e non socket, questo meccanismo non può essere usato. Inoltre, non è possibile che un'applicazione assegni un nuovo valore a errno. In Windows Sockets la funzione WSASetLastError può essere usata a questo scopo.

Stile BSD tipico

r = recv(...);
if (r == -1
    && errno == EWOULDBLOCK)
    {...}

Stile preferito

r = recv(...);
if (r == -1       /* (but see below) */
    && WSAGetLastError() == EWOULDBLOCK)
    {...}

Anche se le costanti di errore coerenti con Berkeley Sockets 4.3 vengono fornite a scopo di compatibilità, è consigliabile che le applicazioni usino le definizioni di codice di errore WSA. Ciò è dovuto al fatto che i codici di errore restituiti da determinate funzioni di Windows Sockets rientrano nell'intervallo standard di codici di errore definiti da Microsoft C©. Di conseguenza, una versione migliore del frammento di codice sorgente precedente è:

r = recv(...);
if (r == -1       /* (but see below) */
    && WSAGetLastError() == WSAEWOULDBLOCK)
    {...}

La specifica winsock 1.1 originale definita nel 1995 ha consigliato un set di codici di errore ed elenca i possibili errori che possono essere restituiti in seguito a ogni funzione. Windows Sockets 2 ha aggiunto funzioni e funzionalità con altri codici di errore di Windows Sockets restituiti oltre a quelli elencati nella specifica Winsock originale. Nel corso del tempo sono state aggiunte funzioni aggiuntive per migliorare Winsock per l'uso da parte degli sviluppatori. Ad esempio, sono state aggiunte nuove funzioni del servizio dei nomi (getaddrinfo e getnameinfo, ad esempio) che supportano sia IPv6 che IPv4 in Windows XP e versioni successive. Alcune delle funzioni del servizio dei nomi IPv4 meno recenti ,ad esempio la classe getXbyY di funzioni, sono state deprecate.

Nella sezione codici di errore di Windows Sockets è disponibile un elenco completo dei possibili codici di errore restituiti dalle funzioni di Windows Sockets.

Gestione degli errori winsock

Conversione di applicazioni Socket in Winsock

Codici di errore di Windows Sockets

Considerazioni sulla programmazione winsock