我正在研究涉及套接字編程的應用程序。我試圖在服務器因任何原因關閉或崩潰的情況下在此應用程序中實現重置功能。對於重置,我需要在手動重新啓動服務器之後重新建立客戶端和服務器之間的通信。現在,我可以發送客戶端到服務器的請求,哪個服務器會處理並向客戶端發送回覆。 Send()
服務器端功能正在返回成功,但WSAWaitForMultipleEvents()
客戶端功能每次都返回WSA_TIME_OUT
。WSAWaitForMultipleEvents在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;
}
如果在套接字上發生錯誤,在大多數情況下它將變得不可用,並且必須打開一個新的套接字。同樣如果你關閉()它。也許你試圖通過這種不可用的套接字發送/接收? – 2012-07-06 22:44:48
請顯示您的實際代碼。您的描述太模糊,無法用來診斷任何內容。你很可能在客戶端使用WSAWaitForMultipleEvents()錯誤的方式。 – 2012-07-07 08:43:14
我添加了一段代碼。將關閉一個套接字並重新初始化它將被視爲打開一個新的套接字? – 2012-07-07 11:24:04