Re: ConnectEx
- From: Ansuman <Ansuman@xxxxxxxxxxxxxxxxxxxxxxxxx>
- Date: Mon, 29 Jun 2009 13:25:01 -0700
This is just a sample code. It was not going to run on Production. I was
trying to make the ConnectEx working first. This machine has single IP and
fixed IP. Client and Server are both running on the same machine.
I tried as per your suggestion by zeroing out, using WSASocket and used
Event. Here is the new code that I tried. But still not able to connect to
the server.
Server Code
WSADATA wsaData;
LPFN_ACCEPTEX lpfnAcceptEx = NULL;
GUID GuidAcceptEx = WSAID_ACCEPTEX;
WSAOVERLAPPED olOverlap;
SOCKET ListenSocket, AcceptSocket;
sockaddr_in service;
char lpOutputBuf[1024];
int outBufLen = 1024;
DWORD dwBytes;
int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
if( iResult != NO_ERROR )
printf("Error at WSAStartup\n");
ListenSocket = WSASocket(AF_INET,SOCK_STREAM, IPPROTO_TCP, NULL, 0,
WSA_FLAG_OVERLAPPED);
if (ListenSocket == INVALID_SOCKET)
{
printf("Error at socket(): ListenSocket\n");
WSACleanup();
return;
}
hostent* thisHost;
char* ip;
u_short port;
port = 9999;
thisHost = gethostbyname("");
ip = inet_ntoa (*(struct in_addr *)*thisHost->h_addr_list);
memset(&service,0,sizeof(service));
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr(ip);
service.sin_port = htons(port);
if (bind( ListenSocket,(SOCKADDR*) &service, sizeof(service) ) ==
SOCKET_ERROR )
{
printf("bind failed\n");
closesocket(ListenSocket);
return;
}
if (listen( ListenSocket, 100 ) == SOCKET_ERROR)
printf("error listening\n");
printf("Listening on address: %s:%d\n", ip, port);
WSAIoctl(ListenSocket,SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidAcceptEx,
sizeof(GuidAcceptEx),&lpfnAcceptEx, sizeof(lpfnAcceptEx), &dwBytes, NULL,
NULL);
AcceptSocket = WSASocket(AF_INET,SOCK_STREAM, IPPROTO_TCP, NULL, 0,
WSA_FLAG_OVERLAPPED);// socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (AcceptSocket == INVALID_SOCKET)
{
printf("Error creating accept socket.\n");
WSACleanup();
return;
}
memset(&olOverlap, 0, sizeof(olOverlap));
olOverlap.hEvent = ::CreateEvent(0,FALSE,FALSE,0);
BOOL bError = lpfnAcceptEx(ListenSocket,AcceptSocket,lpOutputBuf, outBufLen
- ((sizeof(sockaddr_in) + 16) * 2),sizeof(sockaddr_in) + 16,
sizeof(sockaddr_in) + 16, &dwBytes, &olOverlap);
DWORD dwError = WSAGetLastError();
if (ERROR_IO_PENDING != dwError)
return;
WaitForSingleObject(olOverlap.hEvent,-1);
Client Side:
WSADATA wsaData;
LPFN_CONNECTEX lpfnConnectEx = NULL;
GUID GuidConnectEx = WSAID_CONNECTEX;
WSAOVERLAPPED olOverlap;
DWORD dwBytes;
int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
if( iResult != NO_ERROR )
printf("Error at WSAStartup\n");
int iError = 0;
sockaddr_in service;
SOCKET hSocket = WSASocket(AF_INET,SOCK_STREAM, IPPROTO_TCP, NULL, 0,
WSA_FLAG_OVERLAPPED); // ::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
hostent* thisHost;
char* ip;
u_short port;
port = 9999;
thisHost = gethostbyname("");
ip = inet_ntoa (*(struct in_addr *)*thisHost->h_addr_list);
memset(&service,0,sizeof(service));
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr(ip);
service.sin_port = htons(port);
printf("Connecting on address: %s:%d\n", ip, port);
WSAIoctl(hSocket,SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidConnectEx,
sizeof(GuidConnectEx),&lpfnConnectEx, sizeof(lpfnConnectEx), &dwBytes, NULL,
NULL);
DWORD dwError = WSAGetLastError();
memset(&olOverlap,0,sizeof(OVERLAPPED));
olOverlap.hEvent = CreateEvent(0,FALSE,FALSE,0);
iError = lpfnConnectEx(hSocket, (SOCKADDR*) &service,
sizeof(service),NULL,0,0,&olOverlap);
dwError = WSAGetLastError(); // This line always returns 10022 error code.
if (SOCKET_ERROR == iError)
::closesocket(hSocket);
if (ERROR_IO_PENDING != dwError)
return 0;
WaitForSingleObject(olOverlap.hEvent,-1);
Thanks,
Ansuman.
"Remy Lebeau" wrote:
.
"Ansuman" <Ansuman@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:0FB2F98C-93B5-47F9-97DC-920FAF65C3F3@xxxxxxxxxxxxxxxx
thisHost = gethostbyname("");
ip = inet_ntoa (*(struct in_addr *)*thisHost->h_addr_list);
That code is not guaranteed to work properly of the machine has multiple IP
addresses. The order of the h_addr_list entries is not defined, so you
could end up binding the listening socket to any random IP, and/or the
client trying to connect to a different IP than the listening socket is
actually listening on. You could set the s_addr value to INADDR_ANY instead
so the listening socket binds to all available IPs, and then (if needed) use
getsockname() after AcceptEx() reports a client is connected to know which
IP was connected to.
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr(ip);
service.sin_port = htons(port);
You are not zeroing out the contents of the structure before filling it in
with your values. You are thus leaving some of its fields initialized with
random data from the stack. ALWAYS zero out structures before passing them
to API functions. Most APIS do not respond well to random data being passed
to them.
memset(&olOverlap, 0, sizeof(olOverlap));
BOOL bError = lpfnAcceptEx(ListenSocket,AcceptSocket,...&olOverlap);
In order to use an OVERLAPPED structure with a socket, use WSASocket()
instead of socket() to allocate the socket, so that you can specify the
WSA_FLAG_OVERLAPPED flag.
You also should be assigning an Event object (via CreateEvent()) to the
OVERLAPPED structure's hEvent member as well.
--
Remy Lebeau (TeamB)
- Follow-Ups:
- Re: ConnectEx
- From: Remy Lebeau
- Re: ConnectEx
- From: Len Holgate
- Re: ConnectEx
- References:
- ConnectEx
- From: Ansuman
- Re: ConnectEx
- From: Remy Lebeau
- Re: ConnectEx
- From: Ansuman
- Re: ConnectEx
- From: Remy Lebeau
- ConnectEx
- Prev by Date: RE: File existence checks failing with SMB 2.0 even though file exists
- Next by Date: Re: ConnectEx
- Previous by thread: Re: ConnectEx
- Next by thread: Re: ConnectEx
- Index(es):
Relevant Pages
|