【发布时间】:2011-07-15 09:25:02
【问题描述】:
希望你今天过得愉快。另一个套接字问题,改天:)
我终于安装了 MicroSoft Visual C++ (MSVC++) IDE 以及 Platform SDK,这样我就可以编译 winsock 应用程序了。
这里漏掉了一大堆东西。在 ServerSocket::accept() 函数中,它创建了一个新的 ClientSocket 实例并将它的套接字文件描述符设置为接受()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/
谢谢!!!
更新 - 根据 Ben 的解决方案,我现在使用:void ServerSocket::accept(ClientSocket& sock);,并实现为:ClientSocket mysock; server.accept(mysock);
非常感谢!!!
【问题讨论】:
标签: c++ visual-c++ sockets winsock