Re: ConnectEx

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance




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)



.



Relevant Pages

  • Re: port 4125 closed on my server ?
    ... then I see a listening socket at port 4125 ... but through ISA I can't be connected ... > On the server just logon to the RWW and connect to a server or machine. ...
    (microsoft.public.windows.server.sbs)
  • Detecting a blocked port
    ... In my Carbon/Mach application I am opening a listening socket and would ... like to detect if the OS X firewall is blocking the port, ...
    (comp.sys.mac.programmer.help)
  • Re: port 4125 closed on my server ?
    ... How are you verifying that the port is open? ... steps of seeing end to end communication through the ISA firewall? ... >> Can you check whether the TS Proxy will start a listening socket on port ... >> On the server just logon to the RWW and connect to a server or machine. ...
    (microsoft.public.windows.server.sbs)
  • Re: Opening listening sockets
    ... > I have a program that opens a listening socket on a LAN PC - it listens for a ... > 'connection' on port 8001. ... > typing my external IP address, followed by the port number. ... > my LAN PC, he can not connect. ...
    (microsoft.public.win32.programmer.networks)
  • Re: ConnectEx
    ... But ConnectEx always returns me WSAEINVAL. ... According to the ConnectExdocumentation: ... The parameter s is an unbound or a listening socket. ...
    (microsoft.public.win32.programmer.networks)