2012-07-06 77 views
2

我正在研究涉及套接字编程的应用程序。我试图在服务器因任何原因关闭或崩溃的情况下在此应用程序中实现重置功能。对于重置,我需要在手动重新启动服务器之后重新建立客户端和服务器之间的通信。现在,我可以发送客户端到服务器的请求,哪个服务器会处理并向客户端发送回复。 Send()服务器端功能正在返回成功,但WSAWaitForMultipleEvents()客户端功能每次都返回WSA_TIME_OUTWSAWaitForMultipleEvents在send()成功时返回超时

我重新启动我的套接字在客户端与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; 
} 
+0

如果在套接字上发生错误,在大多数情况下它将变得不可用,并且必须打开一个新的套接字。同样如果你关闭()它。也许你试图通过这种不可用的套接字发送/接收? – 2012-07-06 22:44:48

+0

请显示您的实际代码。您的描述太模糊,无法用来诊断任何内容。你很可能在客户端使用WSAWaitForMultipleEvents()错误的方式。 – 2012-07-07 08:43:14

+0

我添加了一段代码。将关闭一个套接字并重新初始化它将被视为打开一个新的套接字? – 2012-07-07 11:24:04

回答

0

如果贵族死后会有不一定是任何事件都没有。检测TCP中断连接的唯一可靠方法是写入它。第一次写入断开的连接可能会成功,但稍后会失败。

0

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

相关问题