[WINSOCK] AcceptEx

FBIagent

Erfahrenes Mitglied
Guten abend,

ich habe eine Frage zu AcceptEx(). Und zwar würde ich gerne wissen ob der Socket,
den man angegeben hat beim Fehlschlag auf INVALID_SOCKET gesetzt wird.
Die Frage kommt auf, da ich zum Listener Socket einen IO Completion Port erstelle.

C:
#define DATA_LENGTH 1000

typedef struct _PER_IO_DATA {
    SOCKET s;
    OVERLAPPED Overlapped;
    WSABUF buffer;
    unsigned char AcceptBuffer[ DATA_LENGTH ];
    //int AcceptBufferLen;
    unsigned char OpCode;
} PER_IO_DATA, *LPPER_IO_DATA;
...
/* Listener socket */
SOCKET g_Listener = INVAID_SOCKET;
...
/* Init Listener */
static bool InitListener();
...
/* AcceptEx helper */
static void AcceptExHelper();
...
bool InitListener() {
    if ( ( g_Listener = WSASocket( AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED ) ) == INVALID_SOCKET ) {
        return false;
    }

    if ( ( g_ListenerData = ( LPPER_IO_DATA )GlobalAlloc( GPTR, sizeof ( PER_IO_DATA ) ) ) == NULL ) {
        return false;
    }

    g_ListenerData->OpCode = ACCEPT;
//    g_ListenerData->s = g_Listener;

    g_ListenAddr.sin_family = AF_INET;
    g_ListenAddr.sin_addr.s_addr = htonl( INADDR_ANY );
    g_ListenAddr.sin_port = htons( LISTEN_PORT );

    if ( bind( g_Listener, ( PSOCKADDR )&g_ListenAddr, sizeof ( g_ListenAddr ) ) == SOCKET_ERROR ) {
        return false;
    }

    if ( listen( g_Listener, 5 ) == SOCKET_ERROR ) {
        return false;
    }

    if ( CreateIoCompletionPort( ( HANDLE )g_Listener, g_IOCPHandle, ( ULONG_PTR )g_ListenerData, 0) ) == NULL) {
        return false;
    }

    return true;
}
...
void AcceptExHelper() {
    DWORD dwBytes = 0;

    if ( (g_ListenerData = ( LPPER_IO_DATA )GlobalAlloc( GPTR, sizeof ( PER_IO_DATA ) ) ) == NULL ) {
        printf("In AcceptExHelper: GlobalAlloc failed\n");

        for ( DWORD dw2 = 0;dw2 < dw;++ dw2 ) {
            PostQueuedCompletionStatus( g_IOCPHandle, 0, (DWORD)NULL, NULL );
        }

        WaitForMultipleObjects( g_SystemInfo.dwNumberOfProcessors * 2, g_WorkerHandles, TRUE, INFINITE );
        DeInitListener();
        DeInitWinsock();
        return;
    }

    /* g_ListenerData->AcceptBufferLen = DATA_LENGTH; */
    memset( &( g_ListenerData->Overlapped ), 0, sizeof ( OVERLAPPED ) );

    if ( ( g_ListenerData->s = WSASocket( AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, WSA_FLAG_OVERLAPPED ) ) == INVALID_SOCKET ) {
        printf("In AcceptExHelper: WSASocket failed\n");

        for ( DWORD dw2 = 0;dw2 < dw;++ dw2 ) {
            PostQueuedCompletionStatus( g_IOCPHandle, 0, (DWORD)NULL, NULL );
        }

        WaitForMultipleObjects( g_SystemInfo.dwNumberOfProcessors * 2, g_WorkerHandles, TRUE, INFINITE );
        DeInitListener();
        DeInitWinsock();
        return;
    }

    //DWORD flags = 0;

    if ( AcceptEx( ( g_Listener, g_ListenerData->s, ( LPVOID )g_ListenerData->AcceptBuffer, 0/*perIoData->AcceptBufferLen - ( ( sizeof ( SOCKADDR_IN ) + 16 ) * 2 )*/, sizeof ( SOCKADDR_IN ) + 16, sizeof ( SOCKADDR_IN ) + 16, &dwBytes, &( g_ListenerData->Overlapped ) ) == FALSE ) {
        if ( WSAGetLastError() != ERROR_IO_PENDING ) {
            printf("In AcceptExHelper: AcceptEx failed\n");

/*            for ( DWORD dw2 = 0;dw2 < dw;++ dw2 ) {
                PostQueuedCompletionStatus( g_IOCPHandle, 0, (DWORD)NULL, NULL );
            }

            WaitForMultipleObjects( g_SystemInfo.dwNumberOfProcessors * 2, g_WorkerHandles, TRUE, INFINITE );
            DeInitListener();
            DeInitWinsock();*/
            return;
        }
    }
}

Wie man sieht habe ich in InitListener den OpCode der Struktur des Listeners auf
ACCEPT gesetzt(Wert 0). Im WorkerThread frage ich dann den OpCode ab, wenn
dieser auf ACCEPT gesetzt ist weis ich, dass eine AcceptEx operation auf dem
Listener statgefunden hat. Somit kann ich den Rückgabewert fon AcceptEx nicht
verwerten. Nun weis ich nur nicht, ob der socket (g_ListenerData->s) auf INVALID_SOCKET
gesetzt wird, wenn AcceptEx fehl schlägt. In der MSDN stand auch nichts der gleichen.
Wenn der Socket nicht auf INVALID_SOCKET gesetzt wird, was bleiben mir dann
noch an anderen Möglichkeiten zu schauen ob AcceptEx erfolgreich war oder nicht?

Der worker thread sieht wie folgt aus:
C:
DWORD WINAPI WorkerThread( LPVOID lpvData ) {
	DWORD BytesTransfered = 0;
	PULONG_PTR IOCPKey = NULL;
	LPOVERLAPPED Overlapped;
	LPPER_IO_DATA ClientData = NULL;

	while ( true ) {
		BOOL Status = GetQueuedCompletionStatus( g_IOCPHandle, &BytesTransfered, IOCPKey, &Overlapped, INFINITE );

		if ( BytesTransfered == 0 && IOCPKey == NULL && Overlapped == NULL ) {
			/* Shutdown, go out of loop */
			break;
		}

		ClientData = ( LPPER_IO_DATA )IOCPKey;

		if ( Status == FALSE || ( Status == TRUE && BytesTransfered == 0 ) ) {
			/* Connection gone, remove client and continue */
			continue;
		}

		switch ( ClientData->OpCode ) {
			case ACCEPT:
				/* Accosiate new socket with IOCP if it's valid! */
				break;
			case SEND:
				break;
			case RECV:
				break;
			default:
				break;
		}
	}

	return 0;
}

Wäre nicht schlecht wenn mir das jemand beantworten könnte.

Best wishes
FBIagent
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück