Re: Socket shutdown fails



Try to close IOCP, maybe that give some direction for thoughts...
Arkady
"Newborn" <Newborn@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:0D8737A3-FF3B-4D1C-82B2-A4C1D333B29B@xxxxxxxxxxxxxxxx
> I've been thinking about my problem over the night and I wish to rephrase
> the
> question...
>
> What can cause a SOCKET to fail a shutdown() call with WSAENOTCONN even
> though the socket is clearly sending and receiving (and keeps doing so
> after
> the shutdown call)?
>
> Cheers
>
> "Newborn" wrote:
>
>> Hi,
>>
>> Some backround... I'm using an IO completion port based socket server
>> engine. On top of that I have another layer that manages outbound/inbound
>> connections (hiding the SOCKET API calls from the user).
>>
>> When creating outbound connections and then attaching them to the IOCP
>> everything works fine. In this case when the socket needs to be closed
>> the
>> connection just calls shutdown(sock, SD_BOTH) and everything exits
>> gracefully.
>>
>> When creating inbound connections i.e. new socket resulted from an
>> AcceptEX() call something goes wrong. The connection works great up until
>> the
>> time you wish to close it. You call shutdown() as before but this time
>> shutdown returns -1 and WSAGetLastError() returns 10057 -- WSANOTCONN.
>>
>> First of all this makes no sense to me since I have been sending and
>> receiving data on this socket. Secondly the sockets in both the inbound
>> and
>> outbound scenarios are created and attached to the IOCP in the same way.
>>
>> Any idead why shutdown won't work? btw closesocket() works fine but if I
>> read MSDN correctly I shouldn't use it in this case before a successful
>> call
>> to shutdown() since I want the socket to close gracefully.
>>
>> Here are code snippets from different places to show the flow of things.
>>
>> First the incoming way (using completion event)
>>
>> //create the socket
>> (*pSock = socket (AF_INET, SOCK_STREAM, nProtocol))
>>
>> //Set opts (part of the creation)
>> int nOptval = SEND_RECV_TIMEOUT;
>> BOOL bOptval = true;
>> CTcpLib::SetSocketOptions(pSock, SOL_SOCKET, SO_SNDTIMEO,(char *)
>> &nOptval);
>> CTcpLib::SetSocketOptions(pSock, SOL_SOCKET, SO_KEEPALIVE,
>> (char*)&bOptval);
>> CTcpLib::SetSocketOptions(pSock, IPPROTO_TCP, TCP_NODELAY,
>> (char*)&bOptval);
>>
>> //Attach the new socket to a completion port
>> HANDLE hTemp = CreateIoCompletionPort((HANDLE)pSock, hCompletionPort,
>> (DWORD)pSock, 0);
>>
>> //Accept a new socket
>> AcceptEx( *pListenSock, *pSock, szRecvBuffer, 0, sizeof(struct
>> sockaddr_in)
>> + 16, sizeof(struct sockaddr_in) + 16, &dwBytesRecv,poverLapped) ==
>> FALSE)
>>
>> The previous code is called initially when listening, and each time an
>> accept event occurs.
>>
>> Now for when my app initiates an outbound connection...
>>
>> //create the socket
>> (*pSock = socket (AF_INET, SOCK_STREAM, nProtocol))
>>
>> //Set opts (part of the creation)
>> int nOptval = SEND_RECV_TIMEOUT;
>> BOOL bOptval = true;
>> CTcpLib::SetSocketOptions(pSock, SOL_SOCKET, SO_SNDTIMEO,(char *)
>> &nOptval);
>> CTcpLib::SetSocketOptions(pSock, SOL_SOCKET, SO_KEEPALIVE,
>> (char*)&bOptval);
>> CTcpLib::SetSocketOptions(pSock, IPPROTO_TCP, TCP_NODELAY,
>> (char*)&bOptval);
>>
>> //this is done in a seperate thread...
>> boo SyncConnectWithTimeOut(PSOCKET pSock, LPSTR szIP, DWORD dwPortNum,
>> DWORD
>> dwTimeOutMilliSec)
>> {
>> if(!pSock || (*pSock) == INVALID_SOCKET)
>> return false;
>>
>> if(!SetSocketBlockingMode(pSock, MODE_NOT_BLOCKING))
>> return false;
>>
>> if( !SyncConnect(pSock, szIP, dwPortNum) )
>> {
>> if(WSAGetLastError() != 0x00002733)
>> {
>> SetSocketBlockingMode(pSock, MODE_BLOCKING);
>> return false;
>> }
>> }
>>
>> if(!WaitSocketReadyToSendWithTimeOut(pSock, dwTimeOutMilliSec))
>> {
>> SetSocketBlockingMode(pSock, MODE_BLOCKING);
>> return false;
>> }
>>
>> SetSocketBlockingMode(pSock, MODE_BLOCKING);
>>
>> return true;
>> }
>>
>> //called in previous function
>> bool SetSocketBlockingMode(PSOCKET pSock, enum BLOCKING_MODE enMode)
>> {
>> if(!pSock || (*pSock) == INVALID_SOCKET)
>> return false;
>>
>> DWORD dwMode = (DWORD) enMode;
>>
>> WSAAsyncSelect(*pSock, NULL, 0, 0);
>>
>> if(ioctlsocket(*pSock, FIONBIO, &dwMode) == SOCKET_ERROR)
>> return false;
>>
>> return true;
>> }
>>
>> //After SyncConnectWithTimeOut() completes successfully the socket is
>> attached to the IOCP
>> HANDLE hTemp = CreateIoCompletionPort((HANDLE)pSock, hCompletionPort,
>> (DWORD)pSock, 0);
>>
>>
>> Thanks for any help!


.



Relevant Pages

  • Re: Socket shutdown fails
    ... How happen if you close completion port before shutdown(), ... > connections (hiding the SOCKET API calls from the user). ... > When creating outbound connections and then attaching them to the IOCP ...
    (microsoft.public.win32.programmer.networks)
  • Re: Socket shutdown fails
    ... > there is no way to 'disassociate' a handle from the completion port. ... >>> connections (hiding the SOCKET API calls from the user). ... >>> When creating outbound connections and then attaching them to the IOCP ... You call shutdown() as before but this time ...
    (microsoft.public.win32.programmer.networks)
  • RE: Socket shutdown fails
    ... What can cause a SOCKET to fail a shutdown() call with WSAENOTCONN even ... > When creating outbound connections and then attaching them to the IOCP ... > boo SyncConnectWithTimeOut(PSOCKET pSock, LPSTR szIP, DWORD dwPortNum, DWORD ...
    (microsoft.public.win32.programmer.networks)
  • Re: Socket shutdown exception
    ... I beleive that shutdown you do on working socket not listening, ... >I have a socket that is is accepting any new connections asynschronously. ...
    (microsoft.public.win32.programmer.networks)
  • Asynchronous Socket Server data
    ... The socket server knows what type of data it expects due to the interface ... I can have 1 databuffer only for each datatype to handle multiple connections? ... int bytesRead = handler.EndReceive; ... packetIndex, bytesRead); ...
    (microsoft.public.dotnet.languages.csharp)