希望您度過美好的一天。另一個套接字問題,另一天:)Winsock accept()返回WSAENOTSOCK(代碼10038)
我終於得到MicroSoft Visual C++(MSVC++)IDE安裝,再加上Platform SDK,所以我可以編譯winsock應用程序。
在這裏錯過了一大堆東西。在ServerSocket :: accept()函數中,它創建一個ClientSocket的新實例,並將它的套接字文件描述符設置爲accept()ed的那個,我也在那裏檢查過,並且它認識到描述符在那裏也是有效的。在我的ClientSocket :: recv()函數中,我顯然調用了winsock庫中的recv()函數。我遇到的問題是,我正在使用的套接字描述符被recv()識別爲無效,但僅在從我的ServerSocket :: accept()返回的服務器端ClientSocket實例上 - 客戶端ClientSocket實例沒有問題。我插入了多個調試語句,描述符是有效的。
最奇怪的是,如果我編譯這個完全相同的代碼與Windows上的MinGW gcc/g ++,它運行良好!它只使用MSVC++發生此問題。
string ClientSocket::recv(int bufsize) {
if (!isConnected()) throw SocketException("Not connected.");
cout << "SocketRecv: " << (sockfd == INVALID_SOCKET) << " " << sockfd << endl;
vector<char> buffer(bufsize+1, 0);
cout << "SocketRecv1: " << (sockfd == INVALID_SOCKET) << " " << sockfd << endl;
int ret = ::recv(sockfd, &buffer[0], bufsize, 0);
cout << "SocketRecv2: " << (sockfd == INVALID_SOCKET) << " " << sockfd << endl;
// ret is apparently -1 because of "invalid" socket descriptor, but the
// above statements print zero (false) on the (sockfd == INVALID_SOCKET) ! :\
if (ret < 0) {
#ifdef _WIN32
switch((ret = WSAGetLastError())) {
#else
switch(errno) {
#endif
case DECONNREFUSED: // The 'd' prefix means _I_ defined it, i.e. from windows it's
// set to 'WSAECONNREFUSED', but from linux it's set to 'ECONNREFUSED'
throw SocketException("Connection refused on recover.");
break;
case DENOTCONN:
throw SocketException("Not connected.");
break;
case DECONNABORTED:
throw SocketException("Software caused connection abort.");
break;
case DECONNRESET:
throw SocketException("Connection reset by peer.");
break;
default:
//usually this itoa() and char/string stuff isn't here... needed it in
//order to find out what the heck the problem was.
char tmp[21];
string tmp4 = "Unknown error reading socket. ";
string tmp3 = tmp4 + itoa(ret, tmp, 10);
//this throw keeps throwing "Unknown error reading socket. 10038"
throw SocketException(tmp3);
break;
}
} else if (ret == 0) {
connected = false;
return "";
}
return &buffer[0];
}
附加信息:套接字處於阻止模式,即尚未設置爲非阻塞。我已成功調用WSAStartup()。這發生在服務器端,在從我的ServerSocket :: accept()返回的ClientSocket實例上(是的,我也在那裏檢查了描述符 - 這很好)。客戶端聲明'WSAECONNRESET(10054)'或'WSAECONNABORTED(10053)'。
我想不出任何其他可能是錯誤的。最糟糕的部分是,在windows和linux上都使用MinGW gcc/g ++都可以正常工作。
如果你想看到整個庫,它粘貼在:(注意:600+線)
Socket.cxx - http://paste.pocoo.org/show/353725/
Socket.hxx - http://paste.pocoo.org/show/353726/
謝謝!
更新 - 按照本公司的解決方案,我現在使用:void ServerSocket::accept(ClientSocket& sock);
,並作爲實施:ClientSocket mysock; server.accept(mysock);
太謝謝你了!
那麼,你會如何建議從ServerSocket :: accept()返回ClientSocket?我寧願不要強制使用指針:\ – FurryHead 2011-03-14 22:48:37
非常感謝。我現在正在編譯它,我確實希望它能解決這個問題。 – FurryHead 2011-03-14 22:53:04
HALELUJAH!它的工作原理是使用'無效的ServerSocket :: accept(ClientSocket&sock);'和:'ClientSocket mysock; server.accept(mysock);'謝謝!你不知道這一直困擾着我多久。 – FurryHead 2011-03-14 22:55:19