Condividi tramite


Codici di errore - errno, h_errno e WSAGetLastError

Nelle applicazioni Winsock, i codici di errore vengono recuperati usando la funzione WSAGetLastError, che è il sostituto di Windows Sockets per la funzione di Windows GetLastError. 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 il getXbyY classe di funzioni, i codici di errore non vengono resi disponibili tramite la variabile h_errno. La funzione WSAGetLastError è progettata per fornire un modo affidabile per un thread in un processo multithread di ottenere informazioni sugli errori del 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) ridefinirono le tipiche costanti di errore di Berkeley, tipicamente trovate in errno.h su BSD, come errori WSA equivalenti di Windows Sockets. 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 nel Microsoft Windows Software Development Kit (SDK), nel Platform Software Development Kit (SDK) e in Visual Studio contiene ancora un blocco di definizioni commentato all'interno di un blocco con #ifdef 0 ed #endif che definisce i codici di errore del socket BSD come identici alle 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 il Winsock2.h e rimuovere il commento da questo blocco. Tuttavia, agli sviluppatori di applicazioni è fortemente sconsigliato decommentare 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 fortemente invitati a usare le costanti di errore WSA nelle applicazioni socket.

Queste definizioni rimangono commentate 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()

In questo modo, il codice di rete, scritto per usare l'errno globale, può 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 utilizzata a questo scopo.

Tipico stile BSD

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

Stile preferito

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

Gli stili precedenti richiedono la ridefinizione delle costanti di errore del socket BSD in costanti di errore WSA affinché funzionino correttamente. Anche se le costanti di errore coerenti con Berkeley Sockets 4.3 vengono fornite a scopo di compatibilità, le applicazioni sono fortemente incoraggiate a usare le definizioni di codice di errore WSA. Questo perché i codici di errore restituiti da determinate funzioni 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. Sono state aggiunte funzioni aggiuntive nel tempo 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 di servizio dei nomi solo per IPv4 meno recenti (ad esempio, la classe di funzioni getXbyY) sono state sconsigliate.

Nella sezione codici di errore di Windows Socketsviene fornito 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