Win Socket UDP无连接recvfrom()错误

时间:2013-07-11 15:07:43

标签: c++ udp communication vc6 winsock2

我正在研究一个传统的VC6应用程序,该应用程序使用winsocket来侦听传入数据包的UDP端口。但是我收到以下错误。如果我使用 WSAGetLastError() ,我会获得 WSAECONNRESET ,如果我阅读说明,那似乎没有意义,因为它说远程主机强行关闭套接字,但是我想使用UDP无连接庄园,所以其他机器正在做什么并不重要...我们应该听。如果我查看 errno 并使用 sterror() ,我会收到以下消息。的 "No such file or directory" 即可。 (根据http://pubs.opengroup.org/onlinepubs/009695399/functions/recvfrom.html

,我认为这是EIO

我在缩小问题方面取得了一些成功,如果我发出一个 sendto() 来电,会回复与 {{相同的端口1}} ,代码似乎工作正常。因此 recvfrom() 的某些内容处于糟糕状态。

我正在寻找有关此套接字变坏的原因以及如何预防或恢复的建议。

修改

这是另一个奇怪的部分,如果再次为该套接字设置(在recvfrom()失败之后)......这一切似乎都有效,甚至对 sendto() 似乎没有触发recvfrom()失败,这反过来会再次调用设置..

CODE

sendto()

主要()

 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
}

0 个答案:

没有答案