надеюсь, у тебя хороший день.Еще одна проблема с сокетом, в другой день:)
Наконец-то у меня установлена IDE MicroSoft Visual C ++ (MSVC ++), а также Platform SDK, так что я могу скомпилировать приложения winsock.
Здесь пропущено множество вещей,В функции ServerSocket :: accept () он создает новый экземпляр ClientSocket и устанавливает дескриптор файла сокета равным тому, который был принят accept (), я также проверил там, и он распознает, что дескриптор также действителен там.
В моей функции ClientSocket :: recv () я вызываю (очевидно) функцию recv () из библиотеки winsock.Проблема, с которой я сталкиваюсь, заключается в том, что дескриптор сокета, который я использую, распознается recv () как недействительный, но только на серверном экземпляре ClientSocket, возвращенном из моего ServerSocket :: accept () - на клиентском экземпляре ClientSocket нетпроблемы.Я вставил несколько операторов отладки, дескриптор действителен.
Самое странное в этом то, что если я скомпилирую этот точно такой же код с MinGW gcc / g ++ для Windows, он будет работать нормально!Эта проблема возникает только при использовании 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 ().Это происходит на стороне сервера, на экземпляре ClientSocket, возвращенном из моего ServerSocket :: accept () (да, я тоже проверил дескриптор - это нормально).Клиентская сторона заявляет «WSAECONNRESET (10054)» или «WSAECONNABORTED (10053)».
Я не могу думать ни о чем другом, что может быть неправильным.Хуже всего то, что он отлично работает, используя MinGW gcc / g ++ для Windows и Linux.
Если вы хотите увидеть всю библиотеку, она вставляется в: (осторожно: 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);
Большое спасибо !!!