mardi 21 février 2017

Socket works at startup but if Server shutdowns and then comes back up I get WSAENOTSOCK

I have a program that is communicating with another over TCP on a specific port. When the "server" side is already started and I start my "client" everything works as expected. However I want my client to be able to reestablish it's connection to the "server" if for some reason the "server" goes offline. Unfortunately every time I restart the "server" I get WSAECONNRESET (10054) for a couple attempts and then eventually I get WSAENOTSOCK (10038) an infinite number of times. How should I create, close and recreate a socket object that's always going to be listening on a specific port?

here are the steps for how I create the socket for listening

m_hostSocket=socket(AF_INET, SOCK_STREAM,IPPROTO_TCP));
BOOL bKeep = TRUE;
setsockopt(m_hostSocket, SOL_SOCKET, SO_KEEPALIVE, (char*)&bKeep, sizeof(bKeep));

Then I connect

SOCKADDR_IN hostRecv;
hostRecv.sin_family=AF_INET;
hostRecv.sin_addr=m_hostIP; //always the same IP
hostRecv.sin_port=htons(m_usPort); //this always the same port
connect(m_hostSocket,(struct sockaddr *) &hostRecv, sizeof(hostRecv));

Then I pass the socket created by the above steps to a thread that reads the data using the select function call to see if we have data to read from and I debug this and get a 1 everytime, meaning we do have something ready to be read from the socket.

SOCKET oSocket = SokcetCreator->m_hostSocket; //use the newly created socket
fd_set oSockets;
FD_ZERO(&oSockets);
FD_SET(oSocket, &oSockets);
iRetVal = select(1, &oSockets, (fd_set*) 0, (fd_set*) 0, NULL);

However when I attempt to call recv on that socket I get the socket error.

int iNumBytesRead = recv(oSocket, oBuffer, iBufferSize, 0 );

The recv always returns a SOCKET_ERROR when I attempt to reestablish the socket to the "server"... Is there something I am doing wrong in creating the socket that would not allow me to reopen the socket on the same port as before?

This is how i close the socket before recreating the socket object.

shutdown(m_hostSocket,SD_BOTH);
closesocket(m_hostSocket);
m_hostSocket=INVALID_SOCKET;

I always am able to recv at the start. I never get errors when recreating the socket with the above steps, it's only when I attempt to recv from the socket after recreation do I get SOCKET_ERROR.

Aucun commentaire:

Enregistrer un commentaire