2

我正在开发一个涉及套接字编程的应用程序。我正在尝试在此应用程序中实现重置功能,以防服务器因任何原因关闭或崩溃。对于重置,我需要在手动重新启动服务器后重新建立客户端和服务器之间的通信。现在我可以将请求从客户端发送到服务器,该服务器将处理并向客户端发送回复。Send()服务器端的函数成功返回,但WSAWaitForMultipleEvents()客户端的函数WSA_TIME_OUT每次都返回。

我在客户端重新启动我的套接字,SO_REUSEADDR重置时具有真实值。我对网络编程很陌生,我无法理解为什么会这样。

这是我在客户端的代码。它有点乱所以请多多包涵

void 
SocketListner::run()
{
    // std::cout << "Thread ID of SocketListener : " << QThread::currentThreadId() << "\n";
    if(_isFrameGrabber)
    {
        _listenForFrames();
    }
     else
    {
        _listenForRequests();
    }
}

void
SocketListner::_listenForRequests()
{
    DWORD eventVal;
    unsigned int eventSock;
    WSANETWORKEVENTS networkEvents;
    std::stringstream ss;

    int bufferLength = 500;
    char * msg = new char[bufferLength];
    std::string Msg = "";
    int retCode;
    int diff;

    while(!_done)
    {
        // Giving it one second less than the condition wait time
   //     OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_destructorMutex);
        if((eventVal=WSAWaitForMultipleEvents(_eventCnt, _socketEvents, false, 3000, false)) == WSA_WAIT_FAILED)
        {
            ss.str("");
            ss << "WSAWaitForMultipleEvents() failed with error : " << WSAGetLastError();
            LOG_ERROR(ss.str());
            emit socketErrorSignal(eventVal);
            break;
        }
        else if(eventVal == WSA_WAIT_TIMEOUT)
        {
            //OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
            if(_done)
            {
                WSACloseEvent(_socketEvents[0]);
                if(_eventCnt==2)
                    WSACloseEvent(_socketEvents[1]);
                break;
            }
            continue;
        }

        if( (diff=(eventVal - WSA_WAIT_EVENT_0)) == 0 )
            eventSock = s_sock;
        else if(diff == 1)
            eventSock = c_sock;
        else 
            continue;

        if((WSAEnumNetworkEvents(eventSock, _socketEvents[eventVal - WSA_WAIT_EVENT_0], &networkEvents)) == SOCKET_ERROR)
        {
            ss.str("");
            ss << "WSAEnumNetworkEvents() failed with error : " << WSAGetLastError();
            LOG_ERROR(ss.str());
            // break;
        }

        if (networkEvents.lNetworkEvents & FD_ACCEPT)
        {
            if (networkEvents.iErrorCode[FD_ACCEPT_BIT] != 0)
            {
                ss.str("");
                ss << "FD_ACCEPT failed with error : " << networkEvents.iErrorCode[FD_ACCEPT_BIT];
                LOG_ERROR(ss.str());
                break;
            }

            if ((c_sock = accept(eventSock, NULL, NULL)) == INVALID_SOCKET)
            {
                ss.str("");
                ss << "accept() failed with error : " << WSAGetLastError();
                LOG_ERROR(ss.str());
                break;
            }

            if ((_socketEvents[_eventCnt] = WSACreateEvent()) == WSA_INVALID_EVENT)
            {
                std::stringstream ss;
                ss << "WSACreateEvent() failed with error : " << WSAGetLastError();
                LOG_ERROR(ss.str());
                break;
            }

            if( WSAEventSelect(c_sock, _socketEvents[_eventCnt], FD_READ | FD_CLOSE) == SOCKET_ERROR)
            {
                ss.str("");
                ss << "WSAEventSelect() failed with error : " << WSAGetLastError();
                LOG_ERROR(ss.str());
                break;
            }

            ++_eventCnt;
        }

        if(networkEvents.lNetworkEvents & FD_READ)
        {
            if (networkEvents.lNetworkEvents & FD_READ && networkEvents.iErrorCode[FD_READ_BIT] != 0)
            {
                ss.str("");
                ss << "FD_READ failed with error : " << networkEvents.iErrorCode[FD_READ_BIT];
                LOG_ERROR(ss.str());
            }

            if((retCode = recv(eventSock, msg, bufferLength, 0)) > 0)
            {
                int place = 0;
                while(place < retCode)  
                {
                    if(msg[place] == '\n' && Msg.length() != 0)
                    {
                        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
                        //Naresh: Replacing std::vector by std::queue
                        _requests.push(Msg);
                        Msg = "";
                    }
                    else
                    {
                        if(msg[place] != '\0')
                            Msg.push_back(msg[place]);
                    }
                    ++place;
                }
            }
            //Abhishek: Testing Complete else block
            else if(retCode == 0 || WSAGetLastError() == WSAECONNRESET)
            {
                //Abhishek
                shutdown(c_sock, SD_BOTH);
                shutdown(s_sock, SD_BOTH);
                closesocket(c_sock);
                closesocket(s_sock);
                int error = WSAGetLastError();

                if(!_initialize())
                {
                    _done = true;
                    return;
                }
            }
            else if(retCode == SOCKET_ERROR)
            {
                bool stopListening=false;
                int errorCode = WSAGetLastError();
                _processSocketError(errorCode, stopListening);          

                if(stopListening)
                {
                    LOG_WARNING("Connection with the partner lost.");
                    emit socketErrorSignal(errorCode);
                    break;
                }
            }
        }

        if(networkEvents.lNetworkEvents & FD_CLOSE)
        {
            if (networkEvents.iErrorCode[FD_CLOSE_BIT] != 0)
            {
                ss.str("");
                ss << "FD_CLOSE failed with error : " <<  networkEvents.iErrorCode[FD_CLOSE_BIT];
                LOG_ERROR(ss.str());
                emit socketErrorSignal(networkEvents.iErrorCode[FD_CLOSE_BIT]);
            }
            else if(!_stopped)
            {
                LOG_ERROR("Lost Connection with Wall.");
                emit socketErrorSignal(networkEvents.iErrorCode[FD_CLOSE_BIT]);
            }

            closesocket(eventSock);
            break;
        }
        //Sleep(100);
    } //While

    delete[] msg;
    msg = NULL;

    // If any failure occurs make the _bDone  variable to true, as thread is no longer running
    _cleanUpCondition.signal();
}

这是_initialize函数

bool 
SocketListner::_initialize()
{
    if(_IP.length() <= 0)
    {
        LOG_ERROR("Host IP Address : " + _IP + " is invalid.");
        return false;
    }

    //Naresh: replacing vector by queue
    while(!_requests.empty())
    {
        _requests.pop();
    }

    WSADATA wsaData;

    if(WSAStartup(0x101,&wsaData) != 0)
    {
        LOG_ERROR("Failed WSAStartUp() call.");
        return false;
    }

    sockaddr_in SockAddr;

    SockAddr.sin_family = AF_INET;
    SockAddr.sin_port = htons(_port);
    SockAddr.sin_addr.s_addr =  inet_addr(_IP.c_str());

    s_sock = socket(AF_INET,SOCK_STREAM,0);
    //Abhishek:BugFix for reset enable address reuse else bind() will fail
    bool addrReuse = true;
    setsockopt(s_sock, SOL_SOCKET, SO_REUSEADDR, (const char*) &addrReuse, sizeof(BOOL));

    if(!_isFrameGrabber)
    {
        if ((_socketEvents[_eventCnt] = WSACreateEvent()) == WSA_INVALID_EVENT)
        {
            std::stringstream ss;
            ss << "WSACreateEvent() failed with error : " << WSAGetLastError();
            LOG_ERROR(ss.str());
            return false;
        }

        if(WSAEventSelect(s_sock, _socketEvents[_eventCnt], FD_ACCEPT | FD_CLOSE)== SOCKET_ERROR)
        {
            std::stringstream ss;
            ss << "WSAEventSelect() failed with error : " << WSAGetLastError();
            LOG_ERROR(ss.str());
            return false;
        }
        ++_eventCnt;
    }

    if(s_sock == INVALID_SOCKET)
        return false;

    int errorCode = bind(s_sock,(sockaddr*)&SockAddr,sizeof(SockAddr));

    if(errorCode == SOCKET_ERROR)
    {
        bool stopListening = false;

        _processSocketError(WSAGetLastError(), stopListening);
        return false;
    }

    if(listen(s_sock,10)!=0)
    {
        return false;
    }

    return true;
}
4

2 回答 2

0

我找到了解决我的问题的方法。现在我在我的应用程序中重新启动所有线程和套接字。之后我发现服务器无法发送,因为它无法连接新的套接字。我放置了一个无限循环以尝试在我的sendData()函数中连接到客户端套接字。这对我有用。

于 2012-07-12T09:34:05.860 回答
0

如果对等体死亡,则根本就不一定有任何事件。在 TCP 中检测断开连接的唯一可靠方法是写入它。第一次写入断开的连接可能会成功,但稍后会失败。

于 2012-07-11T23:32:00.907 回答