Winsock error on accept function - c++

I'm trying to make a simple botnet(not for evil purposes) with winsock, the client is ok(at least at the syntax), but the server has error when i call the accept function, it returns SOCKET_ERROR, i called WSAGetLastError() to get the error number and it returned 10014. In the MSDN page, it says this:
Bad address.
The system detected an invalid pointer address in attempting to use a pointer argument of a call. This error occurs if an application passes an invalid pointer value, or if the length of the buffer is too small. For instance, if the length of an argument, which is a sockaddr structure, is smaller than the sizeof(sockaddr).
Well, i don't have any idea of what to do.
botnetserver.cpp
#include <winsock2.h>
#include <windows.h>
#include <iostream>
#define PORT 5051
#define BUFFMAX 1024 // Buffer max
using namespace std;
int main() {
SOCKADDR_IN svaddr; // server address
SOCKADDR_IN claddr; // client addres
SOCKET listensocket;
SOCKET client;
WSADATA WsaData;
char buffer[BUFFMAX];
int i = sizeof(client);
//ShowWindow(GetConsoleWindow(), SW_HIDE);, fail
WSAStartup(MAKEWORD(2, 2), &WsaData);
listensocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
svaddr.sin_family = AF_INET;
svaddr.sin_port = htons(PORT);
svaddr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(listensocket, (SOCKADDR*) &svaddr, sizeof(svaddr));
client = listen(listensocket, 5)) == SOCKET_ERROR
accept(listensocket, (SOCKADDR*)&claddr, &i) // Error here
while(true) {
/* other things i tried
cout << "\n\n" << buffer << "\n\n";
cout << o << "\n";
buffer[BUFFMAX] = '\0';*/
recv(client, buffer, BUFFMAX, 0);
if(strcmp(buffer, "<fim>") != 0) {
system(buffer);
//break;
} else {break;}
}
closesocket(client);
closesocket(listensocket);
WSACleanup();
system("pause");
}

There are two mistakes in your code:
int i = sizeof(client);
i needs to be initialized as sizeof(claddr) instead. This is what accept() is failing on. sizeof(client) is smaller than sizeof(claddr) so accept() thinks your claddr buffer is too small to receive the client's IP address. This is clearly stated in the documentation you quoted:
The system detected an invalid pointer address in attempting to use a pointer argument of a call. This error occurs if an application passes an invalid pointer value, or if the length of the buffer is too small. For instance, if the length of an argument, which is a sockaddr structure, is smaller than the sizeof(sockaddr).
client = listen(listensocket, 5)) == SOCKET_ERROR
client is a SOCKET handle. You cannot assign the result of the == operator to a SOCKET. You need to assign the result of accept() to client instead.
Change those lines to look like this instead:
int i = sizeof(claddr);
...
listen(listensocket, 5);
client = accept(listensocket, (SOCKADDR*)&claddr, &i);
With that said, you also need to fix your recv() loop. recv() does not return null-terminated data, but strcmp() requires that. You need to null-terminate the buffer after reading, or use strncmp() instead, using the result of recv() as the buffer length. And you need to take into account that it may take multiple calls to recv() to receive <fim>, so you need to implement proper buffering.
And, you need to add proper error handling on ALL function calls.

Related

Why isn't AF_INET working with SOCK_STREAM?

I'm just starting out on gaining a better understanding of socket programming, and I'm trying to build a simple program that can send and receive messages. I've run into an issue with binding a socket to an address to use it. Here is what I have-
#include "stdafx.h"
using namespace std;
int main()
{
bool devbuild = true;
WSADATA mainSdata;
SOCKET sock = INVALID_SOCKET;
sockaddr tobind;
tobind.sa_family = AF_INET;
char stringaddr[] = "192.168.1.1";
inet_pton(AF_INET,stringaddr,&tobind);
//initiating Windows Socket API (WSA)
if (WSAStartup(2.2, &mainSdata) == 0)
{
if (devbuild == true)
{
printf("WSA successfully started...\n");
}
}
else
{
printf("WSA failed to set up, press [ENTER] to exit...\n");
pause();
return 1;
}
//instantiating the socket
sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, NULL);
if (sock != INVALID_SOCKET)
{
if (devbuild == true)
{
printf("Socket successfully created...\n");
}
}
else
{
printf("Socket failed to set up, press [ENTER] to exit...\n");
pause();
return 2;
}
//binding the socket
if (bind(sock, &tobind, sizeof(tobind)) == 0)
{
if (devbuild == true)
{
printf("Socket successfully bound...\n");
}
}
else
{
printf("Socket failed to bind, press [ENTER] to exit...\n");
printf("Last WSA error was: %d", WSAGetLastError());
pause();
return 3;
}
pause();
return 0;
}
I'm getting a return of 3, with WSA error code 10047
10047 - WSAEAFNOSUPPORT
Address family not supported by protocol family.
An address incompatible with the requested protocol was used. All sockets are created with an associated address family (that is, AF_INET for Internet Protocols) and a generic protocol type (that is, SOCK_STREAM). This error is returned if an incorrect protocol is explicitly requested in the socket call, or if an address of the wrong family is used for a socket, for example, in sendto.
This doesn't make sense, because I am only using SOCK_STREAM and AF_INET, which support one another.
I believe one problem (possibly not the only problem, but this is what jumps out at me) is in this line:
inet_pton(AF_INET,stringaddr,&tobind);
The problem is that you are passing &tobind as the final argument, and tobind is a sockaddr, but inet_pton() expects its third argument to point to a struct in_addr instead when using AF_INET (the fact that inet_pton() takes a void-pointer rather than a typed pointer for its third argument makes this kind of mistake really easy to make).
So what you should be doing instead is (note added error checking also):
if (inet_pton(AF_INET,stringaddr,&tobind.sin_addr) != 1)
printf("inet_pton() failed!\n");
Also, you need to make tobind be of type struct sockaddr_in rather than just a sockaddr, and also you need to zero out the struct before using it:
struct sockaddr_in tobind;
memset(&tobind, 0, sizeof(tobind)); // make sure the uninitialized fields are all zero
tobind.sa_family = AF_INET;
[...]

Calling accept() causes WSAEFAULT 10014 Bad address

I'm writing a custom TCP server for Windows, using MinGW compiler and winsock2 API.
I have this piece of code:
TCPSocket TCPSocket::accept() {
TCPSocket clSocket;
struct sockaddr_in clAddr;
socklen_t clAddrSize;
clAddrSize = sizeof(clAddr);
clSocket.shared->sockFd = ::accept(shared->sockFd, (struct sockaddr *)&clAddr, &clAddrSize);
if (clSocket.shared->sockFd < 0) {
printf("failed to accept incoming connection (code: %d)\n", WSAGetLastError());
throw SocketException(6, "failed to accept incoming connection");
}
clSocket.shared->buffer = new byte [BUFFER_SIZE];
clSocket.shared->curPos = clSocket.shared->endPos = clSocket.shared->buffer;
return clSocket;
}
However after calling accept() i get
failed to accept incoming connection (code: 10014)
which is according to MSDN:
WSAEFAULT
10014
Bad address.
The system detected an invalid pointer address in attempting to use a pointer argument of a call. This error occurs if an application
passes an invalid pointer value, or if the length of the buffer is too
small. For instance, if the length of an argument, which is a sockaddr
structure, is smaller than the sizeof(sockaddr).
I don't see, how these pointers can be bad, they both directly address a local variable. The clAddrSize is initialized and shared->sockFd is initialized in another function
void TCPSocket::listen(uint16_t port, int backlog) {
struct addrinfo * ainfo;
char portStr[8];
int res;
if (shared->sockFd != -1)
logicError(1, "socket already initialized, need to close first");
snprintf(portStr, sizeof(portStr), "%hu", (ushort)port);
if (getaddrinfo("localhost", portStr, NULL, &ainfo) != 0)
systemError(2, "failed to retrieve info about localhost", false);
shared->sockFd = socket(ainfo->ai_family, SOCK_STREAM, IPPROTO_TCP);
if (shared->sockFd < 0)
systemError(3, "failed to create a TCP socket", false);
res = bind(shared->sockFd, ainfo->ai_addr, ainfo->ai_addrlen);
if (res != 0)
systemError(5, "failed to bind socket to local port", true);
res = ::listen(shared->sockFd, backlog);
if (res != 0)
systemError(6, "failed to set socket to listen state", true);
freeaddrinfo(ainfo);
}
Do you see anything that i overlooked?
Ok, so thanks to CristiFati i found the problem.
The function getaddrinfo("localhost", portStr, NULL, &ainfo) used that way was returning an IPv6 address. While accept was getting sockaddr_in, which is a struct for IPv4 address.
It could be probably solved more ways, for example
using sockaddr_in6 for IPv6 communication
telling getaddrinfo to to search only IPv4 results with 3rd argument
picking up next result in the linked list returned by getaddrinfo
But i chose to manualy init the socket for IPv4 protocol this way:
struct sockaddr_in myAddr;
memset(&myAddr, 0, sizeof(myAddr));
myAddr.sin_family = AF_INET;
myAddr.sin_port = htons((ushort)port);
shared->sockFd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (shared->sockFd < 0)
systemError(3, "failed to create a TCP socket", false);
res = bind(shared->sockFd, (struct sockaddr *)&myAddr, sizeof(myAddr));
if (res != 0)
systemError(5, "failed to bind socket to local port", true);
Since that, everything works.

Win Socket UDP connection-less recvfrom() Error

I'm working on a legacy VC6 application, that uses winsocket to listen to a UDP port for incoming packets. However I am getting the following errors. If I use WSAGetLastError() I get WSAECONNRESET, which if I read the description, doesn't seem to make sense, because its saying that remote host forcibly closed the socket, But I want use UDP connection-less manor, so it shouldn't matter what the other machine is doing... we should just listen. If I check the errno and use sterror() I get the following message. "No such file or directory". (I think this it's enum is EIO, according to http://pubs.opengroup.org/onlinepubs/009695399/functions/recvfrom.html)
I've had some success in narrowing down the issue, it appears if I take out a sendto() call, that calls back on the same port as the recvfrom(), the code seems to work ok. So something with that sendto() is putting in a bad state.
I'm looking for suggestions on why this socket is going bad, and either how to prevent or recover.
Edit
Here is the other weird part, if do the setup again for that socket (after a recvfrom() fails)... it all seems to work, even additional calls to sendto() don't seem trigger a recvfrom() fail, which in turn would call the setup again..
CODE
static VOID SetupSocketAddress( SOCKADDR_U &saRx, int nRTDPort )
{
memset(&saRx.saIPX, 0, sizeof(SOCKADDR_IPX));
saRx.saIPX.sa_family = AF_IPX; // IPX type address
memset(saRx.saIPX.sa_netnum,0x00,4); // we may have to get this number
memset(saRx.saIPX.sa_nodenum,0xff,6); // broadcast address
saRx.saIPX.sa_socket=(unsigned short)nRTDPort; // socket number
}
void CRealTimeData::SetupSocket( CRealTimeData * lpRTD, BOOL &bDone, SOCKADDR_U &saRx, int nRTDPort, SOCKADDR_U &saFrom, int &cbAddr,
DWORD &dwLocalAddress, int &nMaxIpIpxBuf, char * &pbyIpIpxRxBuf, int nFlags, BOOL bDo)
{
char szErrorCode[32];
int nReturn = 0;
if (lpRTD->m_eSourceType == V7_RTD_IPX)
{
// open IPX socket
// packet type = 4
lpRTD->m_Socket=socket(AF_IPX, SOCK_DGRAM, NSPROTO_IPX+4);
if (lpRTD->m_Socket == INVALID_SOCKET)
{
nReturn = AddSocketErrorToEventViewer( lpRTD);
bDone = TRUE;
}
// Socket must be bound prior to calling recvfrom()
// setup address
SetupSocketAddress(saRx, nRTDPort);
#ifdef _DEBUG_IPX
// test changing host number to network number
// we can't actually change though, because other programs use it this way
u_short nNetPort=0;
int nRet=WSAHtons(lpRTD->m_Socket, (unsigned short)nRTDPort, &nNetPort);
TRACE(_T("RTDIpxThread: Host Port=%04x Net Port=%04x RTD Input=%d \n"),nRTDPort, nNetPort, lpRTD->GetInputNumber());
#endif
// setup address for Sending Data on RTD
SetupSocketAddress( lpRTD->m_saRTD, nRTDPort );
// copy address - Why are we copying the address just over right later (in recvfrom() )? -NG
memcpy(&saFrom.saIPX, &lpRTD->m_saRTD.saIPX, sizeof(SOCKADDR_IPX));
cbAddr = sizeof(SOCKADDR_IPX);
}
else
{
// open IP socket
lpRTD->m_Socket=socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); // ??? should this use IPPROTO_UDP???
if (lpRTD->m_Socket == INVALID_SOCKET)
{
nReturn = AddSocketErrorToEventViewer( lpRTD);
bDone = TRUE;
}
// Socket must be bound prior to calling recvfrom()
// setup address
memset(&saRx.saIP, 0, sizeof(SOCKADDR_IN));
saRx.saIP.sin_family = AF_INET; // IP type address
saRx.saIP.sin_port=htons((u_short)nRTDPort); // PORT number
saRx.saIP.sin_addr.s_addr=htonl(INADDR_ANY); // ADDRESS number
// setup for Sending Data on RTD port
memset(&lpRTD->m_saRTD.saIP, 0, sizeof(SOCKADDR_IN));
lpRTD->m_saRTD.saIP.sin_family = AF_INET; // IP type address
lpRTD->m_saRTD.saIP.sin_port=htons((u_short)nRTDPort); // PORT number
lpRTD->m_saRTD.saIP.sin_addr.s_addr=htonl(INADDR_BROADCAST); // ADDRESS number
// copy address - Why are we copying the address just over right later (in recvfrom() )? -NG
memcpy(&saFrom.saIP, &lpRTD->m_saRTD.saIP, sizeof(SOCKADDR_IN));
cbAddr = sizeof(SOCKADDR_IN);
char szHostName[MAX_PATH+1];
if (gethostname(szHostName, MAX_PATH)==0)
{
hostent *phe=gethostbyname(szHostName);
dwLocalAddress = *(DWORD*)&phe->h_addr_list[0];
}
} // end IP socket
if (!bDone)
{
// enable broadcasting
BOOL bOptVal=TRUE;
nReturn=setsockopt(lpRTD->m_Socket, SOL_SOCKET, SO_BROADCAST, (char *)&bOptVal, sizeof(BOOL));
if (nReturn == SOCKET_ERROR)
{
nReturn=WSAGetLastError();
}
// enable reuse of address
bOptVal=TRUE;
nReturn=setsockopt(lpRTD->m_Socket, SOL_SOCKET, SO_REUSEADDR, (char *)&bOptVal, sizeof(BOOL));
if (nReturn == SOCKET_ERROR)
{
nReturn=WSAGetLastError();
}
// get the socket's max message size
int nOptSize=sizeof(UINT);
UINT nMaxMsgSize=600;
nReturn=getsockopt(lpRTD->m_Socket, SOL_SOCKET, SO_MAX_MSG_SIZE, (char *)&nMaxMsgSize, &nOptSize);
if (nReturn == SOCKET_ERROR)
{
nReturn=WSAGetLastError();
nMaxMsgSize=600; // default max size
}
nMaxIpIpxBuf=nMaxMsgSize; // always create buffer that is as big as the sockets max message size
pbyIpIpxRxBuf = new char[nMaxIpIpxBuf]; // allocate buffer for receiving data from socket
if (!pbyIpIpxRxBuf)
bDone = TRUE;
else
memset(pbyIpIpxRxBuf,0,nMaxIpIpxBuf*sizeof(char));
// bind to address
nReturn=bind(lpRTD->m_Socket, &saRx.sa, cbAddr);
if (nReturn == SOCKET_ERROR)
{
nReturn = AddSocketErrorToEventViewer(lpRTD);
bDone = TRUE;
}
// send data to indicate startup
if (lpRTD->m_eProtocol == V7_RTD_ENHANCED)
{
int nLen=lpRTD->BuildErrorMsg(V7_ERTD_SERVICE_STARTUP, szErrorCode, sizeof(szErrorCode));
nReturn=sendto(lpRTD->m_Socket,szErrorCode,nLen, nFlags, &lpRTD->m_saRTD.sa, cbAddr);
if (nReturn == SOCKET_ERROR)
{
nReturn=WSAGetLastError();
}
}
} // end if not done
}
Main()
nFromLen = cbAddr;
nReturn=recvfrom(lpRTD->m_Socket, pbyIpIpxRxBuf, nMaxIpIpxBuf, nFlags, &saFrom.sa, &nFromLen);
if(nReturn == SOCKET_ERROR)
{
SetupSocket(lpRTD, bDone, saRx, nRTDPort, saFrom, cbAddr, dwLocalAddress, nMaxIpIpxBuf, pbyIpIpxRxBuf,nFlags, FALSE);
nReturn=recvfrom(lpRTD->m_Socket, pbyIpIpxRxBuf, nMaxIpIpxBuf, nFlags, &saFrom.sa, &nFromLen);
}
// if i take this out no error....
nReturn=sendto(lpRTD->m_Socket, szErrorCode, nLen, nFlags, &saFrom.sa, cbAddr);

Multipe Send()'s and Recv()'s using Winsock2

I am working on a small networking project using Winsock2. I am using a TCP connection and actually am working with IRC as an example since IRC is fairly simple. What I am doing is connecting to the server and sending an initial buffer so the server recognizes a connection. This works fine.
What concerns me is that I cannot write to the socket again. It seems my program hangs if I do not use shutdown() (on SD_SEND) after I send the initial buffer.
So the next data (based on RFC 1459) I want to send is the USER and NICK information, however, I feel like using shutdown() is what is causing my current issue. Is there a way to reinitialize the write socket?
Thanks!
ADDED CODE
Note that these are located within a class so it still may be slightly obscured. I am writing it into a simpler example using the elements I have. Everything is properly defined, so if I forget to define things, I apologize, but many of my recurring variables are defined for the scope of the class.
int main(int argc,char *argv[])
{
int iResult;
SOCKET Connection;
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if(iResult != 0)
throw "Startup failed!";
// Prep stuff
ZeroMemory(&hints,sizeof(hints)); // This struct is defined addrinfo
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Now resolve server addr
iResult = getaddrinfo(argv[1],argv[2],&hints,&result);
if(iResult != 0)
throw "getaddrinfo() failed!";
// Now try to connect
for(ptr=result;ptr != NULL;ptr = ptr->ai_next)
{
Connection = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); // defined in that "hints" struct. argument number 2
if(Connection == INVALID_SOCKET)
{
freeaddrinfo(result);
WSACleanup();
throw "Error at socket();";
}
// Connect to server
iResult = connect(Connection, ptr->ai_addr, (int)ptr->ai_addrlen);
if(iResult != 0)
{
closesocket(Connection);
Connection = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
// Send initial buffer so server know you're there :)
iResult = send(Connection, "", 1, 0);
if(iResult == SOCKET_ERROR)
{
close();
throw "Could not send initial buffer!";
}
// Close this connection for the inital buffer
iResult = shutdown(Connection, SD_SEND);
if(iResult == SOCKET_ERROR)
{
close();
throw "Could not close initial buffer socket!";
}
bool connected = true;
// This is taken from my read function within the class
// BEGIN READ FUNCTION
iResult = 0; // Reset
std::string data = ""; // Capture the output and send it all at once!
// This only works if we're connected sweet cakes <3
if(connected)
{
do
{
iResult = recv(socket, recvbuf, BUFLEN, 0);
if(iResult > 0)
{
// Working properly
// Save all data even if there is more than BUFLEN sent
continue;
}
else if(iResult == 0)
// Connection closed properly
break;
else
printf("ERROR!");
} while(iResult > 0);
}
data += recvbuf;
ZeroMemory(&recvbuf,sizeof(recvbuf));
// Function returns std::string but essentially this is what happens
printf("%s",data.c_str());
// END READ FUNCTION
// BEGIN WRITE FUNCTION
iResult = 0; // Reset
SOCKET socket = Connection; // Write function arg 1
char *data; // Write function arg 2
iResult = send(socket,data,(int)strlen(data),0);
if(iResult == SOCKET_ERROR)
{
close();
printf("Could not write data: %ld",WSAGetLastError());
return 1;
}
// Data sent, let's close the write socket
iResult = shutdown(socket, SD_SEND);
if(iResult != 0)
{
close();
printf("Could not close write socket!");
return 1;
}
//return iResult;
// END WRITE FUNCTION
// Now that will produce "Could not write data: 0" for any value of data
// So realistically I want to send the USER and NICK data, then read
// and probably process a PING string from the server and send my PONG response
return 0;
}
I hope that clarifies things!
EDIT
I think I have figured out what is going wrong. I made the corrections listed below to my code; thanks guys. However, it's my read loop which is messing with things. Even after it has all the information it seems that it is waiting for the connection to be closed before it sends the output. Any ideas? My output currently looks like this (the bytes written/total is something I added to make sure everything was going down the wire correctly)
Bytes Written: 41
Bytes Total: 41
Data: ERROR :Closing Link: raged123[127.0.0.1] 6667 (Ping timeout)
...
:irc.foonet.com NOTICE AUTH :*** Found your hostname (cached)
PING :2ED39CE5
[A bunch of funny characters]WinSock 2.0
So it appears to have timed out because the PING did not receive PONG in time, however, I cannot send the PONG without first processing the PING request which means I would need to be able to read the output before the connection is closed. Any ideas?
May I suggest a fun document on the subject? Chapter's 6 and 7 of Beej's Guide to Network Programming
It has several examples.
There shouldn't be any need to send an "initial buffer" like you've done. The server will receive notification when a client connects, it doesn't depend on the client actually sending anything. (And in particular, the IRC protocol says that the server will start sending you stuff as soon as you connect.)
The call to shutdown() is highly suspicious. Why did you expect to need to do this? Shutting down a socket is something you do when you're done with the connection, not when you're just starting. You should remove this completely.
I'm not sure what type recvbuf is, but it looks like you're using it incorrectly. Something that can be appended to a std::string probably can't also have ZeroMemory() called on it, without one or the other of those being wrong. You also aren't using iResult which is the actual number of bytes received from the server.
Your write function also contains a call to shutdown(), which you should remove.
According to man send(2)
On success, these calls return the
number of characters sent. On error,
-1 is returned, and errno is set appropriately.
What happens is probably that send does not send the full buffer at once, you must use a loop around it.
This might not be your actual problem however since you,re sending an empty string...
I'd highly recommend using Wireshark so you can check what goes down to the wire
data += recvbuf;
This can't work. There's no way string::operator+= to know how many bytes have been received. This function expects a C-style string, not an arbitrary chunk of bytes.
But you also have a very fundamental design problem. You're expecting your program to speak the IRC protocol, but it contains no implementation of that protocol whatsoever. For example, the IRC protocol specifies a particular way that messages are delimited, and you have no code whatsoever to parse those messages.
As a result, your transition from reading to writing occurs at essentially a random time determined by the vagaries of TCP timing and how the server chooses to segment its output. Since the server is permitted to segment its output however it pleases (the protocol is clear that the client cannot rely on segmentation to parse the protocol but instead must rely on the line-oriented nature), your program's behavior is unpredictable.

Socket send recv functions

I have created a socket using the following lines of code.
Now i change the value of the socket i get like this
m_Socket++;
Even now the send recv socket functions succeeds without throwing SOCKET_ERROR.
I expect that it must throw error.
Am i doing something wrong.
struct sockaddr_in ServerSock; // Socket address structure to bind the Port Number to listen to
char *localIP ;
SOCKET SocServer;
//To Set up the sockaddr structure
ServerSock.sin_family = AF_INET;
ServerSock.sin_addr.s_addr = INADDR_ANY;
ServerSock.sin_port = htons(pLantronics->m_wRIPortNo);
// To Create a socket for listening on wPortNumber
if(( SocServer = socket( AF_INET, SOCK_STREAM, 0 )) == INVALID_SOCKET )
{
return FALSE;
}
//To bind the socket with wPortNumber
if(bind(SocServer,(sockaddr*)&ServerSock,sizeof(ServerSock))!=0)
{
return FALSE;
}
// To Listen for the connection on wPortNumber
if(listen(SocServer,SOMAXCONN)!=0)
{
return FALSE;
}
// Structure to get the IP Address of the connecting Entity
sockaddr_in insock;
int insocklen=sizeof(insock);
//To accept the Incoming connection on the wPortNumber
pLantronics->m_Socket=accept(SocServer,(struct sockaddr*)&insock,&insocklen);
if(pLantronics->m_Socket == INVALID_SOCKET)
{
shutdown(SocServer, 2 );
closesocket(SocServer );
return FALSE;
}
// To make socket non-blocking
DWORD dwNonBlocking = 1;
if(ioctlsocket( pLantronics->m_Socket, FIONBIO, &dwNonBlocking ))
{
shutdown(pLantronics->m_Socket, 2);
closesocket(pLantronics->m_Socket);
return FALSE;
}
pLantronics->m_sModemName = inet_ntoa(insock.sin_addr);
Now i do
m_Socket++;//change to some other number ideally expecting send recv to fail.
Even now the send recv socket functions succeeds without throwing SOCKET_ERROR.
I expect that it must throw error.
Am i doing something wrong.
It's because of the peculiar nature of Windows handles -- when created they are divisible by four and when used their two lowest bits are ignored. Incrementing a handle by one will make m_Socket refer to the same socket as before (only when you increment by four will the function return an error -- unless there is another handle with that value open).
You should not probe for open handles in this manner. While there are other ways to enumerate open handles, you shouldn't use them. Do not depend on the system to keep track of your handles -- track them yourself.