Created
November 28, 2012 04:07
-
-
Save joeyadams/4158972 to your computer and use it in GitHub Desktop.
Working ConnectEx example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <WinSock2.h> | |
#include <MSWSock.h> | |
#include <WS2tcpip.h> | |
#pragma comment(lib, "Ws2_32.lib") | |
struct mswsock_s { | |
LPFN_CONNECTEX ConnectEx; | |
} mswsock; | |
static BOOL load_mswsock(void) | |
{ | |
SOCKET sock; | |
DWORD dwBytes; | |
int rc; | |
/* Dummy socket needed for WSAIoctl */ | |
sock = socket(AF_INET, SOCK_STREAM, 0); | |
if (sock == INVALID_SOCKET) | |
return FALSE; | |
{ | |
GUID guid = WSAID_CONNECTEX; | |
rc = WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, | |
&guid, sizeof(guid), | |
&mswsock.ConnectEx, sizeof(mswsock.ConnectEx), | |
&dwBytes, NULL, NULL); | |
if (rc != 0) | |
return FALSE; | |
} | |
rc = closesocket(sock); | |
if (rc != 0) | |
return FALSE; | |
return TRUE; | |
} | |
int main(int argc, char *argv[]) | |
{ | |
int rc; | |
BOOL ok; | |
WSADATA wsaData; | |
SOCKET sock; | |
rc = WSAStartup(MAKEWORD(2,2), &wsaData); | |
if (rc != 0) { | |
printf("WSAStartup failed: %d\n", rc); | |
return 1; | |
} | |
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { | |
printf("Your computer is from the wrong millenium.\n"); | |
WSACleanup(); | |
return 1; | |
} | |
if (!load_mswsock()) { | |
printf("Error loading mswsock functions: %d\n", WSAGetLastError()); | |
return 1; | |
} | |
sock = socket(AF_INET, SOCK_STREAM, 0); | |
if (sock == INVALID_SOCKET) { | |
printf("socket: %d\n", WSAGetLastError()); | |
return 1; | |
} | |
/* ConnectEx requires the socket to be initially bound. */ | |
{ | |
struct sockaddr_in addr; | |
ZeroMemory(&addr, sizeof(addr)); | |
addr.sin_family = AF_INET; | |
addr.sin_addr.s_addr = INADDR_ANY; | |
addr.sin_port = 0; | |
rc = bind(sock, (SOCKADDR*) &addr, sizeof(addr)); | |
if (rc != 0) { | |
printf("bind failed: %d\n", WSAGetLastError()); | |
return 1; | |
} | |
} | |
/* Issue ConnectEx and wait for the operation to complete. */ | |
{ | |
OVERLAPPED ol; | |
ZeroMemory(&ol, sizeof(ol)); | |
sockaddr_in addr; | |
ZeroMemory(&addr, sizeof(addr)); | |
addr.sin_family = AF_INET; | |
addr.sin_addr.s_addr = inet_addr("173.194.37.36"); // google.com | |
addr.sin_port = htons(80); | |
ok = mswsock.ConnectEx(sock, (SOCKADDR*) &addr, sizeof(addr), NULL, 0, NULL, &ol); | |
if (ok) { | |
printf("ConnectEx succeeded immediately\n"); | |
} else if (WSAGetLastError() == ERROR_IO_PENDING) { | |
printf("ConnectEx pending\n"); | |
DWORD numBytes; | |
ok = GetOverlappedResult((HANDLE) sock, &ol, &numBytes, TRUE); | |
if (ok) | |
printf("ConnectEx succeeded\n"); | |
else | |
printf("ConnectEx failed: %d\n", WSAGetLastError()); | |
} else { | |
printf("ConnectEx failed: %d\n", WSAGetLastError()); | |
return 1; | |
} | |
} | |
/* Make the socket more well-behaved. */ | |
rc = setsockopt(sock, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0); | |
if (rc != 0) { | |
printf("SO_UPDATE_CONNECT_CONTEXT failed: %d\n", WSAGetLastError()); | |
return 1; | |
} | |
/* This will fail if SO_UPDATE_CONNECT_CONTEXT was not performed. */ | |
rc = shutdown(sock, SD_BOTH); | |
if (rc != 0) { | |
printf("shutdown failed: %d\n", WSAGetLastError()); | |
return 1; | |
} | |
printf("Done\n"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment